m$$DISKBLOCK055.DۀDISKBLOCK055.DBACKUP/NOASSIST/NODISMOUNT/COMMENT=VAX/VMS SPKITBLD Procedure/INTER/LOG/VERIFY DISK$USER:[RANCE.DISKBLOCK.KIT055.SOURCE]*.* DISK$DUMP:[PUBLIC]DISKBLOCK055.D/LABEL=(DISKBLOCK)/SAVE/BLOCK=9000/GROUP=25/NOINIT/NOREWIVAX/VMS SPKITBLD Procedure RANCE  DY"V6.2 _VIVIAN::  _$1$DUA43: V6.2 $T+*[RANCE.DISKBLOCK.KIT055.SOURCE]CHECKSUM.C;2+,^ZF. / 4P `-fJ0123KPWO 5 6wo-7dc 8du*9G HJ#include "diskblock.h"O/* This is the routine called by the CHECKSUM command from the command line */void checksum(void){O extern unsigned char rw_buff[512]; /* Main READ/WRITE buffer */O const $DESCRIPTOR(home_qual,"HOMEBLOCK"); /* CLI Qualifier */O const $DESCRIPTOR(depos_qual,"DEPOSIT"); /* " " */O int status, /* VMS return status */O deposit; /* Flag to show CHECK /DEPOSIT */% status = CLI$PRESENT(&depos_qual);# if ($VMS_STATUS_SUCCESS(status)) deposit = TRUE; else deposit = FALSE;@/* For CHECKSUM/HOME we first check the checksum at offset 58 */$ status = CLI$PRESENT(&home_qual);# if ($VMS_STATUS_SUCCESS(status))1 checksum_buffer(rw_buff,TRUE, 58, deposit);L/* The checksum at offset 510 gets checked for CHECKSUM and CHECKSUM/HOME *// checksum_buffer(rw_buff,TRUE, 510, deposit); } /* End of CHECKSUM */F/* Routine to validate an ODS2 checksum at any offset in any buffer */unsigned long checksum_buffer(O unsigned char *buff, /* Address of buffer */O int message, /* TRUE = print status info */O int offset, /* # of bytes to checksum */O int deposit_flag /* TRUE = deposit new checksum */ ){O unsigned long checksum, /* Accumulated checksum */O old_checksum, /* Checksum in buffer */A i; /* loop counter */* /* Get original checksum from buffer */7 old_checksum = buff[offset] | (buff[offset+1] << 8); checksum = 0;P /* Accumulate new checksum (add buffer as unsigned words, discard overflow */& for (i=0; i <= (offset/2 - 1); i++)B checksum = checksum + buff[2*i] + ( (buff[(2*i)+1]) << 8); checksum = checksum & 0xffff; if (checksum == old_checksum)A { /* Checksum was valid */A if (message == TRUE) LIB$SIGNAL(&DSKB_CHKVALID,1,checksum);) return 1;  }  elseO { /* Checksum was invalid */ if (deposit_flag == 1)O { /* New checksum is to be written */ extern unsigned short O modify_flag; /* 1 = I/O buffer has been modified */, buff[offset] = checksum & 0x00FF;, buff[offset+1] = (checksum & 0xFF00) >> 8; modify_flag = 1; if (message==TRUE)A LIB$SIGNAL(&DSKB_CHKCHANGED,3,old_checksum,checksum); return 0; } elseO if (message==TRUE) /* Just report invalid checksum */A LIB$SIGNAL(&DSKB_CHKINVALID,3,old_checksum,checksum); return 0; + } /* End of Checksum was invalid */.} /* End of checksum_buffer() */-*[RANCE.DISKBLOCK.KIT055.SOURCE]COMMANDS.CLD;2+,Z6./ 4O-fJ0123KPWO5 6Tl-7 8đu*9G HJMODULE DISKBLOCK_COMMANDS DEFINE VERB READ_BLOCK ROUTINE READ_BLOCK/ PARAMETER P1 LABEL=BLOCK, VALUE (TYPE=$NUMBER); QUALIFIER FID, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER) DEFINE VERB WRITE_BLOCK ROUTINE WRITE_BLOCK/ PARAMETER P1 LABEL=BLOCK, VALUE (TYPE=$NUMBER); QUALIFIER FID, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)! QUALIFIER CHECKSUM, NONNEGATABLE, QUALIFIER FORCED_ERROR, NONNEGATABLE DEFINE VERB REWRITE_BLOCK ROUTINE REWRITE_BLOCK! QUALIFIER CHECKSUM, NONNEGATABLE, QUALIFIER FORCED_ERROR, NONNEGATABLE DEFINE VERB EXAMINE_BUFFER ROUTINE EXAMINE_BUFFER: PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED,TYPE=$NUMBER)9 QUALIFIER TIME, NONNEGATABLE, SYNTAX=EXAMINE_TIMEG QUALIFIER INSTRUCTION, NONNEGATABLE, SYNTAX=EXAMINE_INSTRUCTION* QUALIFIER LONGWORD, NONNEGATABLE, DEFAULT QUALIFIER WORD, NONNEGATABLE QUALIFIER BYTE, NONNEGATABLE7 DISALLOW ANY2(LONGWORD, WORD, BYTE, TIME, INSTRUCTION) DEFINE VERB DEPOSIT_BUFFER ROUTINE DEPOSIT_BUFFER6 QUALIFIER STRING, NONNEGATABLE, SYNTAX=DEPOSIT_STRING9 QUALIFIER TIME, NONNEGATABLE, SYNTAX=DEPOSIT_TIMEA PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED,TYPE=$NUMBER)> PARAMETER P2 LABEL=DATA, VALUE (REQUIRED,TYPE=$NUMBER)* QUALIFIER LONGWORD, NONNEGATABLE, DEFAULT QUALIFIER WORD, NONNEGATABLE QUALIFIER BYTE, NONNEGATABLE2 DISALLOW ANY2(STRING, TIME, LONGWORD, WORD, BYTE) DEFINE VERB UPDATE+ PARAMETER P1 LABEL=OPTION, PROMPT="What?",8 VALUE(REQUIRED,TYPE=UPDATE_OPTIONS) DEFINE VERB FILL_BUFFER ROUTINE FILL_BUFFER> PARAMETER P1 LABEL=DATA, VALUE (REQUIRED,TYPE=$NUMBER)* QUALIFIER LONGWORD, NONNEGATABLE, DEFAULT QUALIFIER WORD, NONNEGATABLE QUALIFIER BYTE, NONNEGATABLE$ DISALLOW ANY2(LONGWORD, WORD, BYTE) DEFINE VERB DUMP_BUFFER ROUTINE DUMP_BUFFER= QUALIFIER BLOCK, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER); QUALIFIER FID, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)% QUALIFIER HEX, NONNEGATABLE, DEFAULT QUALIFIER OCTAL, NONNEGATABLE QUALIFIER ASCII, NONNEGATABLE, QUALIFIER INSTRUCTIONS, NONNEGATABLE QUALIFIER FILE, NONNEGATABLE QUALIFIER HEADER, NONNEGATABLE$ QUALIFIER HOME, NONNEGATABLE- QUALIFIER ALPHA NONNEGATABLE, DEFAULT" QUALIFIER VAX NONNEGATABLE DISALLOW (ALPHA and VAX)4 DISALLOW (ALPHA or VAX) AND NOT INSTRUCTIONSD DISALLOW ANY2 (HEX, OCTAL, ASCII, INSTRUCTIONS, FILE, HEADER, HOME) DEFINE VERB SELECT_DRIVE ROUTINE SELECT_DISK= PARAMETER P1 LABEL=DRIVE, VALUE (REQUIRED,TYPE=$FILE)8 QUALIFIER FILE, NONNEGATABLE, SYNTAX SELECT_FILE! QUALIFIER OVERRIDE, NONNEGATABLE" QUALIFIER WRITE, NEGATABLE QUALIFIER NOMAP, NONNEGATABLE? QUALIFIER HOMELBN, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)@ QUALIFIER INDEXLBN, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)F QUALIFIER FACTOR, NONNEGATABLE, VALUE (REQUIRED, TYPE=$NUMBER), DISALLOW ANY2 (NOMAP,HOMELBN,INDEXLBN,FILE)6 DISALLOW (NOMAP or HOMELBN or FILE) and FACTOR( DISALLOW INDEXLBN and not FACTOR DEFINE VERB DESELECT ROUTINE DESELECT DEFINE VERB SAVE_BUFFER ROUTINE SAVE_BUFFER; QUALIFIER BLOCK VALUE (REQUIRED, LIST, TYPE=BLOCKS)3 PARAMETER P1 LABEL=FILE, VALUE (TYPE=$FILE)* DISALLOW BLOCK.END AND BLOCK.COUNT DEFINE VERB RESTORE_BUFFER ROUTINE RESTORE_BUFFER; QUALIFIER BLOCK VALUE (REQUIRED, LIST, TYPE=BLOCKS)3 PARAMETER P1 LABEL=FILE, VALUE (TYPE=$FILE)* DISALLOW BLOCK.END AND BLOCK.COUNT DEFINE VERB CHECKSUM ROUTINE CHECKSUM& QUALIFIER DEPOSIT, NONNEGATABLE( QUALIFIER HOMEBLOCK, NONNEGATABLE DEFINE VERB SEARCH_DISK ROUTINE SEARCH_DISK* QUALIFIER OUTPUT VALUE (TYPE=$FILE): QUALIFIER BLOCK VALUE (REQUIRED, LIST, TYPE=BLOCKS)7 QUALIFIER STRING NONNEGATABLE VALUE (REQUIRED)9 QUALIFIER HEADER *$DISKBLOCK055.DZ6fJ-[RANCE.DISKBLOCK.KIT055.SOURCE]COMMANDS.CLD;2O NONNEGATABLE VALUE (TYPE=$FILE)& QUALIFIER DUMP NONNEGATABLE& QUALIFIER FULL NONNEGATABLEE QUALIFIER LONGWORD NONNEGATABLE VALUE (REQUIRED, TYPE=$NUMBER)E QUALIFIER WORD NONNEGATABLE VALUE (REQUIRED, TYPE=$NUMBER)E QUALIFIER BYTE NONNEGATABLE VALUE (REQUIRED, TYPE=$NUMBER)) DISALLOW BLOCK.END AND BLOCK.COUNT= DISALLOW ANY2 (LONGWORD, WORD, BYTE, STRING, HEADER)E DISALLOW NOT (LONGWORD or WORD or BYTE or STRING or HEADER)#  DISALLOW FULL AND NOT HEADER DEFINE VERB HELP ROUTINE HELP_REQUEST6 PARAMETER P1 LABEL=TOPIC VALUE (TYPE = $REST_OF_LINE) DEFINE VERB SHOW ROUTINE SHOW_STATUS DEFINE VERB SPAWN ROUTINE SPAWN8 PARAMETER P1 LABEL=COMMAND VALUE (TYPE = $REST_OF_LINE) DEFINE VERB ATTACH ROUTINE ATTACH3 PARAMETER P1 LABEL=PROCESS VALUE (REQUIRED) DEFINE VERB COPY_FILE ROUTINE COPY_FILE, PARAMETER P1 LABEL=LBN VALUE (TYPE=$NUMBER)2 QUALIFIER OUTPUT VALUE (REQUIRED,TYPE = $FILE)4 QUALIFIER FACTOR VALUE (REQUIRED,TYPE = $NUMBER); QUALIFIER FID, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)& QUALIFIER BUFFER, NONNEGATABLE DISALLOW BUFFER and FID DEFINE VERB DIRECTORY ROUTINE DIRECTORY# PARAMETER P1 LABEL=FILENAME; QUALIFIER FID, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER)@ QUALIFIER LBN, NONNEGATABLE, VALUE (REQUIRED,TYPE=$NUMBER,LIST)@ QUALIFIER BACKFID, NONNEGATABLE, VALUE (REQUIRED, TYPE=$NUMBER)J QUALIFIER COUNT, NONNEGATABLE, VALUE (REQUIRED, TYPE=$NUMBER,LIST)M QUALIFIER SELECT, NONNEGATABLE, VALUE (REQUIRED, TYPE=SELECT_OPTIONS)' QUALIFIER DELETED, NONNEGATABLE% QUALIFIER VALID, NONNEGATABLEE QUALIFIER BY_OWNER, NONNEGATABLE, VALUE (REQUIRED, TYPE=$UIC)G QUALIFIER ACE, NONNEGATABLE, VALUE (REQUIRED, TYPE=ACE_OPTIONS)$ QUALIFIER FULL, NONNEGATABLE) QUALIFIER PLACEMENT, NONNEGATABLE1 QUALIFIER BEFORE, NONNEGATABLE, VALUE (REQUIRED)0 QUALIFIER SINCE, NONNEGATABLE, VALUE (REQUIRED)& QUALIFIER BACKUP, NONNEGATABLE' QUALIFIER CREATED, NONNEGATABLE' QUALIFIER EXPIRED, NONNEGATABLE( QUALIFIER MODIFIED, NONNEGATABLE3 QUALIFIER OUTPUT, NONNEGATABLE, VALUE (TYPE=$FILE): DISALLOW ANY2 (BACKUP, CREATED, EXPIRED, MODIFIED)J DISALLOW BEFORE AND NOT (BACKUP or CREATED or EXPIRED or MODIFIED)I DISALLOW SINCE AND NOT (BACKUP or CREATED or EXPIRED or MODIFIED)D DISALLOW (BACKUP or CREATED or EXPIRED or MODIFIED) AND NOT " (SINCE or BEFORE)$ DISALLOW (VALID and DELETED) DISALLOW (FID and LBN)$ DISALLOW (COUNT and not LBN) DEFINE TYPE ACE_OPTIONS& KEYWORD ID, VALUE (TYPE=$UIC)  DEFINE TYPE SELECT_OPTIONSB KEYWORD SIZE, DEFAULT, VALUE (LIST, type=SEL_SIZE_OPTIONS) DEFINE TYPE SEL_SIZE_OPTIONS: KEYWORD MINIMUM_SIZE, DEFAULT, VALUE (DEFAULT="0")H KEYWORD MAXIMUM_SIZE, DEFAULT, VALUE (DEFAULT="1073741823")  DEFINE VERB EXIT ROUTINE DISKBLOCK_EXIT DEFINE VERB SET ROUTINE SET_NYI1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS) DEFINE SYNTAX DEPOSIT_STRING ROUTINE DEPOSIT_STRING QUALIFIER STRING, NONNEGATABLEA PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED,TYPE=$NUMBER)1 PARAMETER P2 LABEL=DATA, VALUE (REQUIRED) DEFINE SYNTAX DEPOSIT_TIME ROUTINE DEPOSIT_TIME# QUALIFIER TIME NONNEGATABLEB PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED, TYPE=$NUMBER)1 PARAMETER P2 LABEL=DATA, VALUE (REQUIRED) DEFINE SYNTAX EXAMINE_TIME ROUTINE EXAMINE_TIME# QUALIFIER TIME NONNEGATABLEB PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED, TYPE=$NUMBER)$ DEFINE SYNTAX EXAMINE_INSTRUCTION# ROUTINE EXAMINE_INSTRUCTION* QUALIFIER INSTRUCTION NONNEGATABLEB PARAMETER P1 LABEL=ADDRESS, VALUE (REQUIRED, TYPE=$NUMBER) DEFINE SYNTAX SELECT_FILE ROUTINE SELECT_FILE< PARAMETER P1 LABEL=FILE, VALUE (REQUIRED,TYPE=$FILE)8 QUALIFIER FILE, NONNEGATABLE, SYNTAX SELECT_FILE+ QUALIFIER WRITE, NEGATABLE, DEFAULT DEFINE SYNTAX UPDATE_HEADER ROUTINE UPDATE_HEADER+ PARAMETER P1 LABEL=OPTION, PROMPT="What?",8 VALUE(REQUIRED,TYPE=UPDATE_OPTIONS): QUALIFIER IDOFFSET, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER MPOFFSET, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER ACOFFSET, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER RSOFFSET, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER SEGNUM, VALUE (REQUIRED, TYPE=$NUMBER)2 QUALIFIER STRUCLEV, VALUE (DEFAULT=%X0201)? QUALIFIER FID, VALUE (REQUIRED, TYPE=$NUMBER,LIST): QUALIFIER FIDNUM, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER FIDSEQ, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER FIDRVN, VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER FIDNMX, VALUE (REQUIRED, TYPE=$NUMBER)? QUALIFIER EXTFID, VALUE (REQUIRED, TYPE=$NUMBER,LIST): QUALIFIER EXTFIDNUM VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER EXTFIDSEQ VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER EXTFIDRVN VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER EXTFIDNMX VALUE (REQUIRED, TYPE=$NUMBER)D !QUALIFIER RECATTR VALUE (REQUIRED, TYPE=RECATTR_TYPE,LIST)@ QUALIFIER FILECHAR VALUE (REQUIRED, TYPE=FILECHAR_TYPE): QUALIFIER MAPINUSE VALUE (REQUIRED, TYPE=$NUMBER), QUALIFIER ACCMODE VALUE (DEFAULT=0)7 QUALIFIER FILEOWNER VALUE (REQUIRED, TYPE=$UIC)= QUALIFIER FILEPROT VALUE (REQUIRED, TYPE=PROTECTION)? QUALIFIER BACKFID VALUE (REQUIRED, TYPE=$NUMBER,LIST): QUALIFIER BKFIDNUM VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER BKFIDSEQ VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER BKFIDRVN VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER BKFIDNMX VALUE (REQUIRED, TYPE=$NUMBER)B QUALIFIER JOURNAL VALUE (REQUIRED, TYPE=JOURNAL_OPTIONS): QUALIFIER RUACTIVE VALUE (REQUIRED, TYPE=$NUMBER): QUALIFIER HIGHWATER VALUE (REQUIRED, TYPE=$NUMBER) !QUALIFIER CLASSPROT ? DISALLOW FID AND (FIDNUM or FIDSEQ or FIDRVN or FIDNMX)N DISALLOW EXTFID AND (EXTFIDNUM or EXTFIDSEQ or EXTFIDRVN or EXTFIDNMX)K DISALLOW BACKFID AND (BKFIDNUM or BKFIDSEQ or BKFIDRVN or BKFIDNMX)O DISALLOW NOT (IDOFFSET or MPOFFSET or ACOFFSET or RSOFFSET or SEGNUM orN STRUCLEV or FID or FIDNUM or FIDSEQ or FIDRVN or FIDNMX J or EXTFID or EXTFIDNUM or EXTFIDSEQ or EXTFIDRVN or F EXTFIDNMX or FILECHAR or MAPINUSE or ACCMODE or O FILEOWNER or FILEPROT or BACKFID or BKFIDNUM or BKFIDSEQ G or BKFIDRVN or BKFIDNMX or JOURNAL or RUACTIVE or HIGHWATER) DEFINE TYPE BLOCKS, KEYWORD START, VALUE (TYPE=$NUMBER), KEYWORD END, VALUE (TYPE=$NUMBER), KEYWORD COUNT, VALUE (TYPE=$NUMBER) DEFINE TYPE UPDATE_OPTIONS: KEYWORD HEADER, NONNEGATABLE, syntax=UPDATE_HEADER DEFINE TYPE SET_OPTIONS3 KEYWORD LOG, NONNEGATABLE, syntax = SET_LOG5 KEYWORD PAGE, NONNEGATABLE, syntax = SET_PAGE9 KEYWORD NOPAGE, NONNEGATABLE, syntax = SET_NOPAGE7 KEYWORD WRITE, NONNEGATABLE, syntax = SET_WRITE; KEYWORD NOWRITE, NONNEGATABLE, syntax = SET_NOWRITE DEFINE TYPE LBNVBN* KEYWORD LBN, VALUE (TYPE=$NUMBER), KEYWORD VBN, VALUE (TYPE=$NUMBER) DEFINE TYPE LBNVBNSIZE* KEYWORD LBN, VALUE (TYPE=$NUMBER), KEYWORD VBN, VALUE (TYPE=$NUMBER)- KEYWORD SIZE, VALUE (TYPE=$NUMBER) DEFINE TYPE PROTECTION2 KEYWORD SYSTEM, VALUE  KEYWORD OWNER, VALUE KEYWORD GROUP, VALUE KEYWORD WORLD, VALUE DEFINE TYPE VOLCHAR_OPTIONS# KEYWORD READCHECK NEGATABLE# KEYWORD WRITCHECK NEGATABLE KEYWORD ERASE NEGATABLE# KEYWORD HIGHWATER NEGATABLE$ KEYWORD CLASS_PROT NEGATABLE5 KEYWORD VALUE, VALUE (REQUIRED, TYPE=$NUMBER) DEFINE TYPE RECATTR_TYPE$ KEYWORD FORTRAN NEGATABLE$ KEYWORD PRINT NEGATABLE$ KEYWORD BLOCK NEGATABLE DEFINE TYPE FILECHAR_TYPE$ KEYWORD BACKUP NEGATABLE$ KEYWORD WRITEBACK NEGATABLE$ KEYWORD READCHECK NEGATABLE$ KEYWORD WRITECHE,b/,$DISKBLOCK055.DZ6fJ-[RANCE.DISKBLOCK.KIT055.SOURCE]COMMANDS.CLD;2O?CK NEGATABLE$ KEYWORD CONTIGB NEGATABLE$ KEYWORD LOCKED NEGATABLE$ KEYWORD CONTIG NEGATABLE$ KEYWORD BADACL NEGATABLE$ KEYWORD SPOOL NEGATABLE$ KEYWORD DIRECTORY NEGATABLE$ KEYWORD BADBLOCK NEGATABLE$ KEYWORD MARKDEL NEGATABLE$ KEYWORD NOCHARGE NEGATABLE$ KEYWORD ERASE NEGATABLE$ KEYWORD WASCONTIG NEGATABLE5 KEYWORD VALUE, VALUE (REQUIRED, TYPE=$NUMBER) DEFINE TYPE JOURNAL_OPTIONS! KEYWORD ONLY_RU NEGATABLE KEYWORD RUJNL NEGATABLE KEYWORD BIJNL NEGATABLE KEYWORD AIJNL NEGATABLE KEYWORD ATJNL NEGATABLE" KEYWORD NEVER_RU NEGATABLE& KEYWORD JOURNAL_FILE NEGATABLE5 KEYWORD VALUE, VALUE (REQUIRED, TYPE=$NUMBER) DEFINE SYNTAX SET_LOG ROUTINE SET_LOG$ QUALIFIER CLOSE NONNEGATABLE1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS)4 PARAMETER P2 LABEL=FILE, VALUE(TYPE=$INFILE) DEFINE SYNTAX SET_PAGE ROUTINE SET_PAGE1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS) DEFINE SYNTAX SET_NOPAGE ROUTINE SET_NOPAGE1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS) DEFINE SYNTAX SET_WRITE ROUTINE SET_WRITE1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS) DEFINE SYNTAX SET_NOWRITE ROUTINE SET_NOWRITE1 PARAMETER P1 LABEL=OPTION, PROMPT="What",5 VALUE(REQUIRED,TYPE=SET_OPTIONS).*[RANCE.DISKBLOCK.KIT055.SOURCE]COMMON_DATA.C;2+,ZI. / 4R -fJ0123KPWO 5 6,g-79 8u*9G HJL/***************************************************************************L * This module contains all data that is used by more than one module in *L * diskblock. The same data needs to be defined as extern in any routine *L * which uses it. *M ***************************************************************************/#include "diskblock.h"?const char carry_on[] = "Do you want to continue? : ";Cconst char use_it[] = "Do you want to use it anyway? ";Rconst char define_help[] = "Define DSKB_HLB dev:[dir]DISKBLOCK.HLB to use help\n";?const $DESCRIPTOR(cr_to_continue, "Type a to continue: ");unsigned short O ast_channel, /* I/O channel for handling ^T ast interrupts */O disk_channel, /* I/O channel for disk reads/writes */ O /* Assorted flags */O modify_flag, /* 1 = I/O buffer has been modified */H access_flag, /* 1 = Selected drive/file has been accessed */O file_flag, /* 1 = File selected, 0 = Disk selected */O protect_flag, /* 1 = SELECT/NOWRITE */O output_flag, /* 1 = SEARCH /OUTPUT, 3=data in buffers */O log_flag, /* 1 = SET LOG file open, 3=data in buffers */O term_flag, /* 1 = SYS$OUTPUT is a terminal */O controlc_flag, /* 1 = Control C has been typed */O controlt_flag; /* 1 = Control T has been typed */unsigned long O last_block, /* VBN/LBN of last block read/written */O last_fid, /* Last FID successfully read/written */O flush_efn, /* EFN used by $SETIMR to flush RMS buffers */O /* Information returned by SYS$GETJPI in MAIN */J pid, /* PID of invoking process */O /* Information returned by SYS$GETDVI in SELECT */O max_block, /* Used for checking user LBNs */O track_size; /* Used as I/O size for search */Ochar real_dev[NAM$C_MAXRSS]; /* Selected device Name */struct dsc$descriptor_s L real_dev_desc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, real_dev };Munsigned char rw_buff[512]; /* Main Read/Write buffer */>$DESCRIPTOR(help_logical,"DSKB_HLB"); /* HELP Library name */Mstruct DSKB_IO dskb_io[2]; /* Descriptions of two possible I/Os */,/* RMS structures used for SEARCH /OUTPUT */Mstruct FAB outfab; /* File attributes block */Mstruct NAM outnam; /* Name block */Mstruct RAB outrab; /* Record attributes block */Mchar outfilespec[NAM$C_MAXRSS]; /* Full filename returned by RMS */,/* RMS structures used for SET LOG */Mstruct FAB logfab; /* File attributes block */Mstruct NAM lognam; /* Name block */Mstruct RAB lograb; /* Record attributes block */Mchar logfilespec[NAM$C_MAXRSS]; /* Full filename returned by RMS */Nint fifteen_secs[2]; /* VMS Quadword for 30 seconds */M/* These arrays are filled in during SELECT to show the indexfile extents */Munsigned long index_lbn[150], /* Starting LBN for this extent */M index_cnt[150], /* Blocks in this extent */M index_tot[150], /* Blocks in this + earlier extents */M vbn_factor; /* Cluster_size*4 + bitmapsize */,*[RANCE.DISKBLOCK.KIT055.SOURCE]COPY_FILE.C;2+,Z.3/ 4R32-fJ0123KPWO45637 8Zu*9G HJ#include "diskblock.h"void copy_file(void){M extern const char carry_on[]; /* "Do you want to continue? */ extern unsigned shortM disk_channel, /* Channel for Disk or File I/O */M file_flag, /* 1 = File selected, 0 = Disk selected */M controlc_flag; /* 1 = control C has been entered */M extern unsigned long max_block, /* Used for checking user LBN */M index_cnt[150]; /* Used to check indexf is mapped */4 void close_rms(struct FAB *fab, struct NAM *nam);M unsigned long status, /* VMS status return */M filename_size, /* Length of input filename */M function, /* VMS $QIO function */M iosb[2], /* VMS I/O status block */M block, /* LBN/FID to be read */M lbn, /* LBN to read from disk */M count, /* Number of LBNs in this extent */M next_fid, /* FID of extension file header */M i; /* Loop counter */? const char default_filespec[] = "SYS$SCRATCH:COPY_FILE.DAT";O const $DESCRIPTOR(lbn_param, "LBN"); /* CLI parameter name */O const $DESCRIPTOR(fid_qual,"FID"); /* CLI qualifier */O const $DESCRIPTOR(file_param, "OUTPUT"); /* CLI qualifier */O const $DESCRIPTOR(buff_qual, "BUFFER"); /* CLI qualifier */M char file_name[NAM$C_MAXRSS]; /* File name entered by user */M $DESCRIPTOR(file_desc,file_name); /* descriptor for "" "" "" */M char full_filespec[NAM$C_MAXRSS]; /* Full filename returned by RMS */M $DESCRIPTOR(full_filedesc,full_filespec); /* descriptor for "" s+$DISKBLOCK055.DZfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]COPY_FILE.C;2R3" "" " */D struct FAB fab; /* File attributes block */D struct NAM nam; /* Name block */D struct RAB rab; /* Record attributes block */N struct fibdef fib; /* File information block used by ACP $QIO */N unsigned short acp_channel; /* $QIO channel used by ACP $QIO */ struct FIB_DESC fib_desc = {* FIB$C_LENGTH,! &fib };N char uchar[ATR$S_UCHAR], /* User file characteristics */N recattr[ATR$S_RECATTR], /* Record characteristics */N uic[ATR$S_UIC], /* File owner UIC */N fpro[ATR$S_FPRO]; /* File protection */J const struct atrdef copy_attrib[5] = /* Pointer to above attributes */ {L {ATR$S_UCHAR, ATR$C_UCHAR, &uchar}, 2 {ATR$S_RECATTR, ATR$C_RECATTR, &recattr},& {ATR$S_UIC, ATR$C_UIC, &uic},) {ATR$S_FPRO, ATR$C_FPRO, &fpro}, {0,0,0} };B unsigned char *aclbuf; /* Buffer to hold ACL from input */O unsigned char *oneace; /* Pointer to one ACE from aclbuf */9 int acllen; /* Total length of ACL */O int this_acllen; /* Length of ACL on current header */I const int objtyp = ACL$C_FILE; /* Object type for sys$change_acl */ struct ITEM_LIST { short int buffer_length; short int item_code; int address; int retlen; } acl_list[2]; O struct atrdef del_acl[2] = /* File attributes used to delete entire ACL */ {! {0, ATR$C_DELETEACL, 0}, {0,0,0} };F struct atrdef copy_acl[2] = /* File attributes used to add ACEs */ {/ {ATR$S_ADDACLENT, ATR$C_ADDACLENT, 0}, {0,0,0} };D struct FH2DEF header; /* Buffer to hold file header */I struct FM2DEF *next_map; /* Pointer to next indexf map pointer */5 unsigned int copy_blocks(int lbn, int block_count,L struct FAB *fab, struct RAB *rab, struct NAM *nam); if (disk_channel == 0) {K /* Print No disk or file selected and immediately return to caller */ LIB$SIGNAL(&DSKB_NOSEL,0); return; } if (file_flag==1) {O /* COPY doesn't make sense if a FILE is selected, only works for DISKs */" LIB$SIGNAL(&DSKB_NOTFILE,0); return; };/* Check for the qualifiers /FID and /BUFFER and /BLOCKS */;/* fill in header with the file header to be copied */$ status = CLI$PRESENT(&buff_qual);? if ($VMS_STATUS_SUCCESS(status)) /* Copy /BUFFER */ { L extern unsigned char rw_buff[512]; /* Main Read/Write buffer */M status = check_header(&rw_buff); /* Is it a valid file header? */' if (!$VMS_STATUS_SUCCESS(status)) {< LIB$SIGNAL(&DSKB_BADHEADER,0,status,0); /* NOPE! */F if (!$VMS_STATUS_SUCCESS(status=(yes_no(carry_on)))) return; } , memcpy (&header, &rw_buff, 512); , } I else /* End of COPY /BUFFER */+ { & status = CLI$PRESENT(&fid_qual);+ if ($VMS_STATUS_SUCCESS(status)) I { /* COPY /FID=nnn */: status = get_integer(&fid_qual,max_block,&block);; if (!$VMS_STATUS_SUCCESS(status)) return; 4 if (fid_to_lbn(block, &block) == 0) return;I } /* End of COPY /FID=nnn */ elseI { /* COPY nnn */; status = get_integer(&lbn_param,max_block,&block);* if (!$VMS_STATUS_SUCCESS(status)) {C if (status == CLI$_ABSENT) LIB$SIGNAL(&DSKB_NOBLOCK,0); return; } K } /* End of COPY nnn */ I status = read_header(&header,block); /* Read the header */' if (!$VMS_STATUS_SUCCESS(status)) {0 LIB$SIGNAL(&DSKB_BADHEADER,0,status,0);= if (!$VMS_STATUS_SUCCESS(status=(yes_no(carry_on)))) return; } }K controlc_flag = 0; /* Flag my be set by an AST */) /* Initialise the output FAB block */ fab = cc$rms_fab;P fab.fab$l_dna = &default_filespec[0]; /* Default filespec */P fab.fab$b_dns = sizeof(default_filespec); /* # Bytes in default filespec */P fab.fab$b_fac = FAB$M_PUT & FAB$M_GET; /* Going to read/write this file */P fab.fab$l_fop = FAB$M_TEF & FAB$M_SQO; /* Truncate file on close */P /* Sequential operations only */P fab.fab$l_nam = &nam; /* Address of expanded name bloc */P fab.fab$b_org = FAB$C_SEQ; /* Sequential file */P fab.fab$b_rfm = FAB$C_FIX; /* Fixed size records */P fab.fab$b_shr = FAB$M_NIL; /* No record sharing */M fab.fab$w_mrs = 512; /* Record size 512 bytes */( /* Initialise the output NAM block */ nam = cc$rms_nam;P nam.nam$l_rsa = &full_filespec; /* Full filename wanted at this address */P nam.nam$b_rss = NAM$C_MAXRSS; /* maximum size of full filename */! /* Initialise the RAB block */ rab = cc$rms_rab;P rab.rab$l_fab = &fab; /* FAB address */P rab.rab$b_rac = RAB$C_SEQ; /* Sequential access */P file_desc.dsc$w_length = NAM$C_MAXRSS; /* Maximum input filename length */ status=cli$get_value(O &file_param, /* Parameter name */O &file_desc, /* Returned string */O &file_desc.dsc$w_length /* Returned length */! );# if ($VMS_STATUS_SUCCESS(status)) {P /* Get the length and address of the filename string into the fab... */D STR$ANALYZE_SDESC(&file_desc, &filename_size, &fab.fab$l_fna);$ fab.fab$b_fns = filename_size; } else { if (status == CLI$_ABSENT) {+ /* Use filename from input file */P get_name(&header,&file_name); /* This routine is in DIRECTORY.C */# fab.fab$l_fna = file_name;$ fab.fab$b_fns = strlen(file_name); } else return; }4 /* Get the EXTENSION fid from this file header */% next_fid = header.FH2$W_EX_FIDNUM;M /* If there is an extension header AND we haven't mapped the index file */M /* Then give the user an opportunity to give up now... */0 if ( (index_cnt[0] == 0) && (next_fid != 0) ) {@ LIB$SIGNAL(&DSKB_NOEXTHDR, 1, next_fid, &DSKB_NOINDEXF,0);: if (!$VMS_STATUS_SUCCESS(status=(yes_no(carry_on)))) return; } /* Create the output file */! status = SYS$CREATE(&fab,0,0); if (status == RMS$_FEX) {I /* This error is because we have specified a version number and */I /* that file already exists, remove the version number from the */I /* filename that we are creating and try again... */ unsigned char *semicolon;K semicolon = strchr(file_name,'\x3b'); /* Find the semicolon */K semicolon[0] = '\0'; /* Replace it with a NULL */K fab.fab$b_fns = strlen(file_name); /* Change the string length */O status = SYS$CREATE(&fab,0,0); /* Try to create the file again */ }$ if (!$VMS_STATUS_SUCCESS(status)) {? LIB$SIGNAL(&DSKB_CREATERR,1,&file_desc,fab.fab$l_stv,0); return; } O /* The file has been successfully created so connect an RMS record stream */< if (!$VMS_STATUS_SUCCESS(status = SYS$CONNECT(&rab,0,0))) {= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,rab.rab$l_sts,0); close_rms(&fab,&nam); return; }6 /* Put out an info message with the new filename */; LIB$SIGNAL(&DSKB_CREATED,2,nam.nam$b_rsl,nam.nam$l_rsa);' /* Check this header for any ACEs */a$DISKBLOCK055.DZfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]COPY_FILE.C;2R3"; /* The ACL in a header runs from ACOFFSET to RSOFFSET */ aclbuf = NULL; acllen = 0;E this_acllen = (header.FH2$B_RSOFFSET - header.FH2$B_ACOFFSET) *2 ; if (this_acllen != 0)C { /* This header has an ACL so copy it to the end of aclbuf */6 aclbuf = realloc(aclbuf, acllen + this_acllen); J memcpy(aclbuf+acllen, /* Destination */J (short *)&header + header.FH2$B_ACOFFSET, /* Source */J this_acllen); /* Length */ acllen += this_acllen;  }G /* Whilst there is still mapping information in this file header, */G /* or another file header to be mapped */< while ( (header.FH2$B_MAP_INUSE !=0) || (next_fid != 0) ) {C for (i=0, next_map=NULL ; (header.FH2$B_MAP_INUSE !=0) ; i++) {; /* Find the count and LBN for the next file extent */9 map_extent(&header, &next_map, &count, &lbn, 0); if (count != 0) 2 LIB$SIGNAL(&DSKB_COPYING,2,count,lbn);N /* If extent has more than 15 blocks then split into 15 block I/Os */ while (count != 0) {& unsigned long block_count; if (count < 15) {# block_count = count; count = 0; } else { block_count = 15;" count = count - 15; }E status = copy_blocks(lbn, block_count, &fab, &rab, &nam);. if (!$VMS_STATUS_SUCCESS(status)) {G /* We have had an error in the copy blocks routine, */G /* retry ONE block at a time */$ if (block_count != 1) {2 count = count + block_count - 1;" block_count = 1;K status = copy_blocks(lbn, block_count, &fab, &rab, &nam);3 if (!$VMS_STATUS_SUCCESS(status)) {O /* We have now found the failing block and reported it. */ } } }$ lbn = lbn + block_count;O if (controlc_flag == 1) /* Check to see if a ^C has been typed */ {$ close_rms(&fab,&nam); return; }; } /* All blocks on This extent done */; } /* All extents on this file header done */0 /* Check for an(other) extension header */ if (next_fid != 0)P { /* There is an extension header */A LIB$SIGNAL(&DSKB_EXTFID,1,next_fid); /* Tell the user */@ if (fid_to_lbn(next_fid,&block) ==0) /* INVALID FID */ { status = 0; next_fid = 0; } else {J if (!$VMS_STATUS_SUCCESS(status=(read_header(&header,block))))G LIB$SIGNAL(&DSKB_RDBADHEADER,2,next_fid,block,status,0); }0 if ( (!$VMS_STATUS_SUCCESS(status)) && @ (!$VMS_STATUS_SUCCESS(status=(yes_no(carry_on))))  ) M next_fid = 0; /* Can't read header */ else . next_fid = header.FH2$W_EX_FIDNUM;; /* Check this header for an access control list */K this_acllen = (header.FH2$B_RSOFFSET - header.FH2$B_ACOFFSET) *2 ; if (this_acllen != 0)I { /* This header has an ACL so copy it to the end of aclbuf */< aclbuf = realloc(aclbuf, acllen + this_acllen);P memcpy(aclbuf+acllen, /* Destination */P (short *)&header + header.FH2$B_ACOFFSET, /* Source */P this_acllen); /* Length */% acllen += this_acllen; }) } /* End of if (next_fid != 0) */@ } /* End of while ( (header.FH2$B_MAP_INUSE != 0)... */O close_rms(&fab,&nam); /* The file has been completely copied, so close it */D /* Now open the output file again using the $QIO ACP interface */D /* to set the File Header contents correctly... */" /* Initialise the fib block */ memset(&fib,0,FIB$C_LENGTH);= /* Copy the File ID from the nam block to the fib block */1 memcpy( &fib.FIB_FID , &nam.nam$w_fid[0], 6 );# /* Set the fib to be writable */ fib.FIB_ACCTL = FIB$M_WRITE;E /* Initialise the descriptor with the full filename for $ASSIGN */. full_filedesc.dsc$w_length = nam.nam$b_rsl;( /* Assign a channel to the device */ status = SYS$ASSIGN(E &full_filedesc, /* Device Name */E &acp_channel, /* Returned Channel number */E 0, /* Access Mode */E 0 /* Mailbox Name */ );$ if (!$VMS_STATUS_SUCCESS(status)) {9 LIB$SIGNAL(&DSKB_ASNERR,1,&full_filedesc,status,0); return; }' function = IO$_ACCESS | IO$M_ACCESS; status = SYS$QIOW(A 0, /* Event Flag Number */A acp_channel, /* I/O channel */A function, /* I/O function code */A iosb, /* I/O status block address */A 0, /* AST Address */A 0, /* AST Parameter */cA &fib_desc, /* P1, fib descriptor */hA 0, /* P2, not used */ A 0, /* P3, not used */A 0, /* P4, not used */ A 0, /* P5, not used */hA 0); /* P6, not used */*5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];($ if (!$VMS_STATUS_SUCCESS(status)) {# /* Failed to open the file */s: LIB$SIGNAL(&DSKB_OPENERR,1,&full_filedesc,status,0); return;h }B /* Now delete any ACEs that got added to the file by default */ function = IO$_MODIFY;  status = SYS$QIOW( < 0, /* Event Flag Number */< acp_channel, /* I/O channel */< function, /* I/O function code */< iosb, /* I/O status block address */< 0, /* AST Address */< 0, /* AST Parameter */< &fib_desc, /* P1, fib descriptor */< 0, /* P2, not used */< 0, /* P3, not used */< 0, /* P4, not used */< &del_acl, /* P5, attributes block */< 0); /* P6, not used */O /* Now copy the Access control list from buffer aclbuf to the output file */; if (acllen > 0) { int acl_left;a acl_left = acllen; oneace = aclbuf; while (acl_left > 0) {l/ copy_acl[0].atr$w_size = oneace[0]+1;"* copy_acl[0].atr$l_addr = oneace; status = SYS$QIOW(C 0, /* Event Flag Number */cC acp_channel, /* I/O channel */eC function, /* I/O function code */eC iosb, /* I/O status block address */oC 0, /* AST Address */eC 0, /* AST Parameter */;C &fib_desc, /* P1, fib descriptor */CC 0, /* P2, not used */ C 0, /* P3, not used */ C 0, /* P4, not used */hC ©_acl, /* P5, attributes block */eC 0); /* P6, not used */ P acl_left -= (oneace[0]); /* Note how many bytes left to do */L oneace += (oneace[0]); /* Step to next ACE in buffer */1 while (oneace[0]==0 && acl_left > 0)  {R oneace++; /ݲ/$DISKBLOCK055.DZfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]COPY_FILE.C;2R38'* Skip past any end of header padding */  acl_left--; }  }u-/* LIB$SIGNAL(&DSKB_ACLERR,0,status,0); */5 LIB$SIGNAL(&DSKB_CPYACL,2,acllen,&full_filedesc);b }A /* Copy the attributes from the original file header buffer */ A /* to the file attributes blocks */  /* File characteristics */ 9 memcpy( &uchar, &(header.FH2$L_FILECHAR),ATR$S_UCHAR);  /* Record Attributes */= memcpy( &recattr, &(header.FH2$W_RECATTR), ATR$S_RECATTR);a /* File Ownere UIC */7 memcpy( &uic, &(header.FH2$L_FILEOWNER), ATR$S_UIC);t /* File Protection */8 memcpy( &fpro, &(header.FH2$W_FILEPROT), ATR$S_FPRO);A /* Close the file again, writing the new attributes */e function = IO$_DEACCESS;, status = SYS$QIOW(A 0, /* Event Flag Number */FA acp_channel, /* I/O channel */LA function, /* I/O function code */cA iosb, /* I/O status block address */rA 0, /* AST Address */A 0, /* AST Parameter */ A &fib_desc, /* P1, fib descriptor */;A 0, /* P2, not used */iA 0, /* P3, not used */&A 0, /* P4, not used */{A ©_attrib, /* P5, attributes block */sA 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];d$ if (!$VMS_STATUS_SUCCESS(status)) {$ /* Failed to close the file */: LIB$SIGNAL(&DSKB_CLOSERR,1,&full_filedesc,status,0); return;  }$ status = SYS$DASSGN(acp_channel);$ if (!$VMS_STATUS_SUCCESS(status)) {9 LIB$SIGNAL(&DSKB_DSNERR,1,&full_filedesc,status,0);( return;  }F /* Tell the user we have successfully copied the file attributes */0 LIB$SIGNAL(&DSKB_CPYATTRIB,1,&full_filedesc); ;} I/* Routine to copy a range of blocks from the input to the output file */r2unsigned int copy_blocks(int lbn, int block_count,K struct FAB *fab, struct RAB *rab, struct NAM *nam) {  extern unsigned shortK disk_channel, /* Channel for Disk or File I/O */ M controlc_flag; /* 1 = control C has been entered */K unsigned long status, /* VMS status return */ K iosb[2], /* VMS I/O status block */SK buffsize, /* QIO buffer size */c K i; /* Loop counter */ K const int function = IO$_READLBLK; /* VMS I/O function code */ 4 void close_rms(struct FAB *fab, struct NAM *nam);K char copy_buffer[512*15]; /* Buffer to hold file data */ L rab->rab$l_rbf = copy_buffer; /* Buffer address for PUTs */L rab->rab$w_rsz = 512; /* Record size for PUTs */L buffsize = 512*block_count; /* Buffer size for $QIO */J status = SYS$QIOW(0, /* Event Flag Number */J disk_channel, /* I/O channel */J function, /* I/O function cod .e */J iosb, /* I/O status block address*/J 0, /* AST Address */J 0, /* AST Parameter */J copy_buffer, /* P1, buffer address */J buffsize, /* P2, buffer size */J lbn, /* P3, LBN */J 0, /* P4, not used */J 0, /* P5, not used */J 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0]; N /* If we have a read error then check for the number of blocks requested.*/N /* if it is only one block then REPORT the error and continue. This */N /* will cause ONE block of the output file to be corrupted! */N /* If we are trying more than one block then return the error to our */N /* caller, who will perform the retrys. */$ if (!$VMS_STATUS_SUCCESS(status)) { if (block_count==1)* {bB LIB$SIGNAL(&DSKB_READERR,1,(iosb[0]>>25) + lbn,status,0); } else {  return status;Q }  }$ for (i=0 ; i < block_count ; i++) {O rab->rab$l_rbf = copy_buffer + 512 * i; /* Buffer address for PUTs */ status = SYS$PUT(rab,0,0);' if (!$VMS_STATUS_SUCCESS(status))  {tA LIB$SIGNAL(&DSKB_PUTERR,2,nam->nam$b_rsl,nam->nam$l_rsa, & fab->fab$l_stv,0); if (block_count==1) {N /* We need to distinguish a FATAL error because the output file */N /* is gone from a read error, that we can continue from. So */N /* let's just prtend a control c was typed 8^) */$ controlc_flag = 1; }P return status; /* Return the error to our caller for retry/abort */ }s } return 1;}i"/* Routine to close an RMS file */0void close_rms(struct FAB *fab, struct NAM *nam){  unsigned int status;_ status = SYS$CLOSE(fab,0,0);l$ if (!$VMS_STATUS_SUCCESS(status))? LIB$SIGNAL(&DSKB_CLOSERR,2,nam->nam$b_rsl,nam->nam$l_rsa,a fab->fab$l_stv,0);}F,*[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2+,ZH.N/ 4XNLV-fJ0123KPWOO5 6It-7d 8du*9G HJ#include "diskblock.h"9/* Given a FID find the corresponding LBN and filename */K Nunsigned long fid_to_name(unsigned int fid, /* Input FID */N char *full_filename, /* returned filename */N unsigned int *lbn, /* returned LBN */N unsigned short valid_flag) /* Input */N /* 0 = print errors */N /* 1 = return errors */N /* 2 = print deleted */N /* files WITHOUT */N /* reporting error */{J extern unsigned long max_block; /* Used for checking LBN */J extern const char carry_on[]; /* "Do you want to continue? */# const char open_bracket[] = "[";$ const char close_bracket[] = "]"; const char dot[] = ".";+ const char unknown_dir[] = "[........]";O struct FH2DEF dir_buffer; /* Buffer for holding a file header */O char filename[9][90]; /* 8 levels of directory + filename */O unsigned short i,j; /* Loop counters */O unsigned long status, /* VMS return status */O next_lbn; /* LBN of next directory */O if (fid_to_lbn(fid,lbn) == 0) return 0; /* Convert the FID to an LBN */O /* LBN is returned to caller */D /* filename[] is an array of 9 character strings */D /* filename[8] to filename[1] hold the directory names */D /* filename[0] holds the file name (FILE.EXT;VERSION) */D /* There are a maximum of 8 directory names per file $DISKBLOCK055.DZHfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2XN`" */D /* e.g. [dir1.dir2.dir3.dir4.dir5.dir6.dir7.dir8]file.ext;vers */+ /* Initialise the 9 character strings */0 for (i=0 ; i<=9 ; i++) filename[i][0] = '\0';H /* Follow the Directory Backlinks to construct a full filename */H /* Get up to 8 directories and one filename. */ for ( i = 0 ; i<=9 ; i++ ) {I if ( (fid == 4) && (i >= 2) ) break; /* Avoid printing [000000. */D if (fid==0) break; /* No more back links */L if (fid_to_lbn(fid,&next_lbn) == 0) return 0; /* FID not valid */1 status = read_header(&dir_buffer,next_lbn);' if (!$VMS_STATUS_SUCCESS(status))O { /* Error reading header */I if (valid_flag == 1) /* DIR/VALID so discard this header */ return status; elseD if ( (valid_flag == 0) || (status != &DSKB_HDRINVFID) )E LIB$SIGNAL(&DSKB_RDBADHEADER,2,fid,next_lbn,status,0); }M /* We have a valid file header in dir_buffer, now get the file name */) get_name(&dir_buffer, filename[i]);M /* Get the BACK FID from the file header to find the next directory */' fid = dir_buffer.FH2$W_BK_FIDNUM;N if (i > 0) /* This is a directory, not the FILE.EXT part of the name */J filename[i][strlen(filename[i])-6] = '\0'; /* Remove .DIR;1 */ elseM /* If this is an EXTENSION header then the backlink points to the */M /* primary header, just discard this header and start again using */M /* the backlink */K if (dir_buffer.FH2$W_SEG_NUM != 0) --i; /* Not real header */$ } /* End of for (i=0 ; ; i++) */J if (fid==0) /* NO directory backlink found */ {L if (valid_flag == 0) /* Does the caller want to know? */) LIB$SIGNAL(&DSKB_INVBACKLINK,0); full_filename[0] = '\0';) strcat(full_filename, unknown_dir);) strcat(full_filename, filename[0]); return 1; }& /* Initialise filename to "[" */ full_filename[0] = '['; full_filename[1] = '\0'; for (j=i-1 ; j>0 ; j--) {# /* Add next directory name */) strcat(full_filename, filename[j]); if (j == 1); /* If this is the last directory then add "]" */. strcat(full_filename, close_bracket); else /* Otherwise add "." */$ strcat(full_filename, dot); }2 /* Now add the FILE.EXT part of the filename */& strcat(full_filename, filename[0]); return 1;} 3/* Directory command called by CLI$_DISPATCH */3/* Performs a sequential read of INDEXF.SYS */3/* and reports files matching selection criteria */void directory(void){ extern unsigned longN index_lbn[150], /* Starting LBN for this extent */N index_cnt[150], /* Blocks in this extent */N index_tot[150], /* Blocks in this + earlier extents */N vbn_factor, /* Cluster_size*4 + bitmapsize */N max_block; /* Used for checking /SEL-SIZE=nnn */ N extern unsigned short disk_channel, /* Channel for Disk I/O */N controlt_flag, /* 1 = control T has been entered */N controlc_flag; /* 1 = control C has been entered */N const $DESCRIPTOR(file_param,"FILENAME"); /* CLI qualifier */N const $DESCRIPTOR(fid_qual, "FID"); /* CLI qualifier */N const $DESCRIPTOR(full_qual, "FULL"); /* CLI qualifier */N const $DESCRIPTOR(place_qual, "PLACEMENT"); /* CLI qualifier */N const $DESCRIPTOR(lbn_qual, "LBN"); /* CLI qualifier */N const $DESCRIPTOR(count_qual, "COUNT"); /* CLI qualifier */N const $DESCRIPTOR(valid_qual, "VALID"); /* CLI qualifier */N const $DESCRIPTOR(backfid_qual, "BACKFID"); /* CLI qualifier */N const $DESCRIPTOR(deleted_qual, "DELETED"); /* CLI qualifier */N const $DESCRIPTOR(by_owner_qual, "BY_OWNER"); /* CLI qualifier */N const $DESCRIPTOR(since_qual, "SINCE"); /* CLI qualifier */N const $DESCRIPTOR(before_qual, "BEFORE"); /* CLI qualifier */N const $DESCRIPTOR(backup_qual, "BACKUP"); /* CLI qualifier */N const $DESCRIPTOR(created_qual, "CREATED"); /* CLI qualifier */N const $DESCRIPTOR(expired_qual, "EXPIRED"); /* CLI qualifier */N const $DESCRIPTOR(modified_qual, "MODIFIED"); /* CLI qualifier */@ const $DESCRIPTOR(max_size_qual, "SELECT.SIZE.MAXIMUM_SIZE");@ const $DESCRIPTOR(min_size_qual, "SELECT.SIZE.MINIMUM_SIZE");N unsigned short i,j,k, /* Loop counters */N found, /* 1 = At least 1 file found */@ full_flag, /* 1 = Directory /FULL */N placement_flag, /* 1 = Directory /PLACEMENT */N valid_flag; /* 0 = Directory */N /* 1 = Directory /VALID */N /* 2 = Directory /DELETED */O unsigned long block_count, /* Number of blocks to read in next $QIO */O count, /* Number of unread blocks in this extent */O lbn, /* LBN to start next $QIO */O backfid, /* FID of directory containing the file */O status, /* VMS status return */O match_lbn, /* LBN that contains a match */O block[101], /* Value(s) specified with /LBN or /FID */O lbn_count[101]; /* Value(s) specified with /COUNT */O unsigned int since_time[2]; /* VMS Quadword date time */O unsigned int before_time[2]; /* VMS Quadword date time */O unsigned char time_flag; /* 0 = no time check */O /* 1 = BACKUP */O /* 2 = CREATED */O /* 3 = MODIFIED */O /* 4 = EXPIRED */O unsigned char dir_buffer[15 * 512]; /* Buffer for holding part of INDEXF */O unsigned char filename[90]; /* Filename in current Header */O $DESCRIPTOR(filename_desc,filename); /* Descriptor for current filename */O unsigned char owner[64]; /* File owner, for /BY_OWNER */O $DESCRIPTOR(owner_desc,owner); /* Descriptor for " */? unsigned owner_id; /* Numeric qequivalent of OWNER */? unsigned min_size; /* Values from /SELECT=SIZE=MAX */O unsigned max_size; /* and /SELECT=SIZE=MIN */ O unsigned char input_name[90]; /* Filename we are looking for */& $DESCRIPTOR(input_desc,input_name);O const char semi_colon[] = ";"; /* For adding version number */O const char dot[] = "."; /* For adding file extension */O unsigned char *offset; /* Point in filename where match is */O char full_filename[NAM$C_MAXRSS]; /* Filename with [. . . ] etc... */O char line[132]; /* Text for output from print_line()*/. /* Routine to do QIOs to read INDEXF.SYS */D unsigned int read_blocks(int lbn, int block_count, char *buffer);E /* Check that we have selected a disk and mapped its index file */ if (disk_channel == 0) {K /* Print No disk or file selected and immediately return to caller */ LIB$SIGNAL(&DSKB_NOSEL,0); return; }K if (index_cnt[0] == 0) /* The index file has not been mapped */ {# LIB$SIGNAL(&DSKB_NOINDEXF,0); return; },/* Directory command -- PARAMETER PARSING */O /* DIR /FID is handled in a separate routine, check for /FID and dispatch */: if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&fid_qual))) {O extern unsigned longOd$DISKBLOCK055.DZHfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2XNQ" max_block; /* Used for checking LBN */: status = get_integer(&fid_qual,max_block,&block[0]);/ if (!$VMS_STATUS_SUCCESS(status)) return;= status = fid_to_name(block[0],&full_filename, &lbn, 0);& if ($VMS_STATUS_SUCCESS(status)) {M sprintf(line,"FID: %8d LBN %8d %s\n", block[0],lbn,full_filename);C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; } return; }& /* Check for /BY_OWNER qualifier */M owner_id = 0; /* Assume /BY_OWNER not specified */M owner_desc.dsc$w_length = 64; /* Reset to original length */M owner_desc.dsc$a_pointer = &owner; /* and address */ status=cli$get_value(G &by_owner_qual, /* Qualifier name */G &owner_desc, /* Returned string */G &owner_desc.dsc$w_length /* Returned length */ );A if ($VMS_STATUS_SUCCESS(status)) /* BY_OWNER was specified */ {G /* Parse the owner field, to find GROUP and MEMBER information */ char *comma;* comma = (char *) strchr(&owner,',');F owner[owner_desc.dsc$w_length] = '\0'; /* Add a terminator */C if (comma != NULL) /* [NAME,NAME] or [GROUP,MEMBER] */ {= if ( strspn(&owner,"[01234567,]") == strlen(owner) ) {5 /* Numeric UIC in format [octal,octal] */, static const unsigned octal = 8;I unsigned temp; /* Temporary storage for integers */I unsigned char *group; /* Pointer to group part of UIC */I unsigned char *member; /* Pointer to member part of UIC */O member = &comma[1]; /* Point member just past the , */O member[strlen(member)-1] = '\0'; /* Terminate member on the ] */O group = &owner[1]; /* Point group just past [" */O comma[0] = '\0'; /* Terminate group on the , */O temp = strtoul(group,NULL,octal);/* Convert group to integer */O owner_id = temp <<16; /* Top word of owner_id is grp */O temp = strtoul(member,NULL,octal);/* Convert member to integer */O owner_id = owner_id | temp; /* Bottom word is member */ } else1 { /* NAMEd UIC in format [NAME,NAME] */N owner_desc.dsc$a_pointer = &comma[1]; /* step past the , */N owner_desc.dsc$w_length = strlen(comma) - 2; /* discard , and ] */ } } if (owner_id == 0) {9 status = sys$asctoid(&owner_desc,&owner_id,0,0);* if (!$VMS_STATUS_SUCCESS(status)) { LIB$SIGNAL(status); return; } }( } /* End of /BY_OWNER qualifier */" /* Check for /FULL qualifier */; if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&full_qual))) full_flag = 1; else full_flag = 0;' /* Check for /PLACEMENT qualifier */< if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&place_qual))) placement_flag = 1; else placement_flag = 0;- /* Check for /SELECT=SIZE=MIN qualifier */? if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&min_size_qual))) {A status = get_integer(&min_size_qual, max_block, &min_size);' if (!$VMS_STATUS_SUCCESS(status)) return; } else min_size = 0;- /* Check for /SELECT=SIZE=MAX qualifier */? if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&max_size_qual))) {A status = get_integer(&max_size_qual, max_block, &max_size);' if (!$VMS_STATUS_SUCCESS(status)) return; } else max_size = 0;8 /* Check for /BACKUP, /CREATED, /EXPIRED, /MODIFIED */= if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&backup_qual))) time_flag = 1; else {B if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&created_qual))) time_flag = 2; else {F if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&expired_qual))) time_flag = 3; else {K if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&modified_qual)))! time_flag = 4; else! time_flag = 0; } }  } 0 /* Check for /BEFORE and /SINCE qualifiers */ if (time_flag != 0) {@ if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&since_qual))) {3 status=get_time(&since_qual, since_time);+ if (!$VMS_STATUS_SUCCESS(status)) return; } else, since_time[0] = since_time[1] = 0;A if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&before_qual))) {5 status=get_time(&before_qual, before_time);+ if (!$VMS_STATUS_SUCCESS(status)) return; } else8 before_time[0] = before_time[1] = 0Xffffffff; }N /* Check for /BACKFID qualifier */> if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&backfid_qual))) {? status = get_integer(&backfid_qual, max_block, &backfid);' if (!$VMS_STATUS_SUCCESS(status)) return; } else backfid = 0;N /* Check for /LBN and /COUNT qualifiers */: if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&lbn_qual))) {O extern unsigned long max_block; /* Used for checking LBN */ : status = get_integer(&lbn_qual,max_block,&block[0]);/ if (!$VMS_STATUS_SUCCESS(status)) return;p lbn_count[0] = 0; 0 /* Get up to 101 LBNs from command line */? for (i=1 ; (i<=101) && $VMS_STATUS_SUCCESS(status) ; i++), {/= status = get_integer(&lbn_qual,max_block,&block[i]);o lbn_count[i] = 0; } ? block[i-1] = 0xFFFFFFFF; /* Flag to show last LBN */r6 /* At this point i = number of LBNs specified */: /* so for DIR /LBN=x i = 2 */N if (i>101) LIB$SIGNAL(&DSKB_FIRST100,0); /* TOO MANY LBNs specified */? if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&count_qual)))  { P /* If one LBN is specified then only lbn_count[0] should be supplied */# for (j=0 ; j <= i-2 ; j++)e {N block_count = max_block - block[j] + 1; /* Largest legal count */C status = get_integer(&count_qual, block_count, &lbn_count[j]);e- if (!$VMS_STATUS_SUCCESS(status))t {i8 LIB$SIGNAL(&DSKB_LBNCOUNTERR,0,status,0); return; }d } }a }? else /* Not /LBN or /FID just a normal directory command */s {J block[0] = 0xFFFFFFFF; /* Flag to show no LBN was specified */. /* Check if a filename was specified? */ status=cli$get_value( J &file_param, /* Parameter name */J &input_desc, /* Returned string */J &input_desc.dsc$w_length /* Returned length */ );' if (!$VMS_STATUS_SUCCESS(status))  { M if (status == CLI$_ABSENT) /* Default file name is * (all files) */ { input_name[0] = '*';( input_desc.dsc$w_length = 1; } elsepK return; /* We can't read the string, just return to caller */e } K input_name[input_desc.dsc$w_length] = '\0'; /* Add a terminator */iQ /* Add .* to the end of the input filename if no extension was specified */n, if ( strpbrk(input_name,dot) == NULL ) {a7 input_name[input_desc.dsc$w_length] = '.';+7 input_name[input_desc.dsc$w_length + 1] = '*';A8 input_name[input_desc.dsc$w_length + 2] = '\0';' input_desc.dsc$w_length += 2; }(O /* Add ;* to the end of the input filename if no version was specified */=3 if ( strpbrk(input_name,semi_colon) == NULL )_ {C7 input_name[input_desc.dsc$w_length] = ';'; 7 input_name[input_desc.dsc$w_length + 1] = '*';d8 input_name[input_desc.dsc$w_length + 2] = '\0';' input_desc.dsc$w_length += 2; }  } controlc_flag = 0;t controlt_flag = 0;)< if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&valid_qual))) e$DISKBLOCK055.DZHfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2XN̆ ' valid_flag = 1; elseW {K /* Check for /DELETED flag */eA if ($VMS_STATUS_SUCCESS(status=CLI$PRESENT(&deleted_qual)))f valid_flag=2; else valid_flag = 0; }/ /* Open the file specified by DIR /OUTPUT */r open_output();E3 /* Loop round the Index File mapping pointers */i3 /* Until we find one with a count of 0 */l= for (i=0, found=0 ; (i<=150) && (index_cnt[i] != 0) ; i++)p { short fid;S if (index_tot[i] < vbn_factor) continue; /* Skip non file_header extents */  count = index_cnt[i];  lbn = index_lbn[i]; L /* Read the next count blocks of the index file 15 blocks at a time */ while (count != 0) {; if (count < 15) { block_count = count; count = 0; } else { block_count = 15;w count = count - 15;N }5 status = read_blocks(lbn, block_count, dir_buffer);e* if (!$VMS_STATUS_SUCCESS(status)) {, count = count + block_count - 1; block_count = 1;/ while (!$VMS_STATUS_SUCCESS(status= = (read_blocks(lbn, block_count,dir_buffer))))i {8 LIB$SIGNAL(&DSKB_READERR,1,lbn,status,0); lbn += 1;! count = count - 1;" } }J /* Look at each of the 15 (or fewer) headers we have just read */2 /* to see if there is a filename match */( for (j=0 ; jFH2$B_MAP_INUSE !=0) ;)" {G /* Find the count and LBN for the next file extent */ K map_extent(header, &next_map, &next_count, &next_lbn, 0);NO if (lbn_count[0] == 0) /* List of LBNs or 1 LBN to match */  { X for (k=0 ; block[k] != 0xffffffff ; k++) /* For each LBN in list */3 if ( (block[k] >= next_lbn) && A (block[k] <= next_lbn + next_count - 1)K% ) status = 1; }d elseC { /* LBN and Count to check */ V for (k=0 ; block[k] != 0xffffffff ; k++) /* For each LBN range */ { if ( ( : (block[k] >= next_lbn) &&H (block[k] <= next_lbn + next_count - 1)" ) ||9 ( (block[k] < next_lbn) &&EE (block[k] + lbn_count[k] > next_lbn)l ) ( ) status = 1; } }$ } }.F /* If /BY_OWNER was specified then check file ownership */A if ( $VMS_STATUS_SUCCESS(status) && (owner_id != 0) ) {fM struct FH2DEF *header; /* Pointer to this file header */ + header = &dir_buffer[j*512]; C if (owner_id != header->FH2$L_FILEOWNER) status = 0;_ } F /* If /BACKFID was specified then check for a match */@ if ( $VMS_STATUS_SUCCESS(status) && (backfid != 0) ) { L struct FH2DEF *header; /* Pointer to this file header */+ header = &dir_buffer[j*512];*B if (backfid != header->FH2$W_BK_FIDNUM) status = 0; } M /* If /DELETED was specified then check this is a deleted file */ C if ( $VMS_STATUS_SUCCESS(status) && (valid_flag == 2) ) { L struct FH2DEF *header; /* Pointer to this file header */+ header = &dir_buffer[j*512];  if (P (header->FH2$W_CHECKSUM != 0) || /* Checksum must be 0 */P (header->FH2$W_FID_NUM != 0) || /* File ID must be 0 */P (header->FH2$V_MARKDEL != 1) /* Marked for delete */ )e status = 0;u }eI /* Check for /BACKUP, /CREATED, /EXPIRED or /MODIFIED time */ D if ( ($VMS_STATUS_SUCCESS(status)) && (time_flag != 0) ) { O struct FH2DEF *header; /* Pointer to this file header */ O struct FI2DEF *ident; /* Pointer to ID area of header */ O unsigned int *check_time; /* Pointer to correct time in hdr */ , header = &dir_buffer[j*512];M if ( (header->FH2$B_MPOFFSET - header->FH2$B_IDOFFSET) < 19 )0H status = 0; /* No room in ID area for Date fields */ else- ident = (struct FI2DEF *) sH ( (short *)header + header->FH2$B_IDOFFSET );' if (status == 0) break;*" switch (time_flag) {_8 case 1: /* DIRECTORY /BACKUP */ {9 check_time = ident->FI2$Q_BAKDATE;  }  break;*8 case 2: /* DIRECTORY /CREATED */ {9 check_time = ident->FI2$Q_CREDATE;n } break; 8 case 3: /* DIRECTORY /EXPIRED */ {9 check_time = ident->FI2$Q_EXPDATE;  } break;8 case 4: /* DIRECTORY /MODIFIED */ {9 check_time = ident->FI2$Q_REVDATE;t } break;I2 } /* End of switch (time_flag) */ if (8 (since_time[1] > check_time[1]) || ( < (since_time[1] == check_time[1]) &&9 (since_time[0] > check_time[0]) )S )# status = 0;  if ( n& (status != 0) &&9 (before_time[1] < check_time[1]) ||c ( = (before_time[1] == check_time[1]) &&c: (before_time[0] > check_time[0]) )a )# status = 0; * , } /* End of (time_flag != 0) */K /* If /SELECT=SIZE or /PLACEMENT was specified then read all */ K /* of the mapping pointers and check if the file is wanted */S if (0 $VMS_STATUS_SUCCESS(status) && K ( (min_size!=0) || (max_size!=0) || (placement_flag==1) ) ( ) {N unsigned file_size, /* Accumulator for size of file */7N next_fid, /* FID of extension file header */N next_lbn, /* LBN of extension file header */N extent_number, /* Used to loop round header */N file_count, /* Count and LBN from a single */N placed_file, /* File is placed */N file_lbn; /* mapping pointer */ N  oa$DISKBLOCK055.DZHfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2XNhl"8 struct FH2DEF *header; /* Pointer to this file header */N struct FM2DEF *next_map; /* Pointer to next map pointer */N extern const char carry_on[]; /* "Do you want to continue? */+ header = &dir_buffer[j*512]; file_size = 0;/ placed_file = 0; ; /* Check that this is a VALID file header */t- status = check_header(header);rN /* If it's a deleted header and /VALID not specified then OK */B if ((status == &DSKB_HDRINVFID) && (valid_flag!=1)) status = 1;aN /* Print the FID of the invalid file to indicate the problem */C if (!$VMS_STATUS_SUCCESS(status) && (valid_flag!=1))& {2 next_fid = lbn - index_lbn[i] + : index_tot[i] - index_cnt[i] -, vbn_factor + 1;D LIB$SIGNAL(&DSKB_SKIPHDR,1,next_fid,0);  } G /* Don't do any more processing for an invalid header */p7 if (!$VMS_STATUS_SUCCESS(status)) break; @ /* Get the EXTENSION fid from this file header */2 next_fid = header->FH2$W_EX_FIDNUM;N /* If there is an extension header AND we haven't mapped the */N /* index file then give give up now... */< if ( (index_cnt[0] == 0) && (next_fid != 0) ) {L LIB$SIGNAL(&DSKB_NOEXTHDR, 1, next_fid, &DSKB_NOINDEXF,0); status = 0;  }M /* If this is an extension header then give up DIR/SIZE now */(M /* the file size is only meaningful for primary headers */ I if ( (placement_flag==0) && (header->FH2$W_SEG_NUM != 0) )  status = 0;EF if ($VMS_STATUS_SUCCESS(status)) /* Extension fid OK */ {N /* Whilst there is still mapping information in this file header, */N /* or another file header to be mapped */L while ( (header->FH2$B_MAP_INUSE !=0) || (next_fid != 0) ) { ; for (extent_number=0, next_map=NULL ; S9 (header->FH2$B_MAP_INUSE !=0) ; t* extent_number++) {5 /* Get size of this extent */}= if ( (min_size!=0) || (max_size!=0) )E {$L /* Find the count and LBN for this file extent */F map_extent(header, &next_map, &file_count, 3 &file_lbn,0);s> file_size = file_size + file_count; } F /* Check this extent for placement pointers */. if (placement_flag==1) {NF map_extent(header, &next_map, &file_count, 3 &file_lbn,1);(@ if (file_count != 0) placed_file = 1; }   } ' if (next_fid != 0) J { /* There is an extension header */ @ if (fid_to_lbn(next_fid,&next_lbn) ==0) M { /* INVALID FID */e& status = 0;( next_fid = 0; }s elseM { /* NO extension header, or INDEXF.SYS is mapped */A status=(read_header(header,next_lbn));H /* Check that this is a VALID file header */I /* If it's a deleted header and /VALID not */ H /* specified then OK */N if ((status == &DSKB_HDRINVFID) && (valid_flag!=1))& status = 1;H /* Print the FID of the invalid file to */H /* indicate the problem */O if (!$VMS_STATUS_SUCCESS(status) && (valid_flag!=1))/ {> next_fid = lbn - index_lbn[i] + ; index_tot[i] - index_cnt[i] -k- vbn_factor + 1;P LIB$SIGNAL(&DSKB_SKIPHDR,1,next_fid,0);  }< if (!$VMS_STATUS_SUCCESS(status))G next_fid = 0; /* Can't read header */i else A next_fid = header->FH2$W_EX_FIDNUM;  } =8 } /* End of if (next_fid != 0) */N } /* End of while ( (header->FH2$B_MAP_INUSE != 0)... */ B if ( (min_size != 0) && (file_size < min_size) ) status = 0; B if ( (max_size != 0) && (file_size > max_size) ) status = 0;@ if ( (placement_flag==1) && (placed_file==0) ) status = 0; K if ( (status != 0) && ( (min_size!=0) || (max_size!=0) ))q {nE sprintf(line,"FID: %8d Blocks Allocated: %d\n", ' fid,file_size);CO if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;a } = } /* End of status success, Ext fid OK. */l< } /* End of SELECT=SIZE and PLACEMENT */, if ($VMS_STATUS_SUCCESS(status))M { /* We had a match on the filename, owner, FID etc. */ M if ($VMS_STATUS_SUCCESS(status=fid_to_name(fid,&full_filename, B &match_lbn,valid_flag))) {9 sprintf(line,"FID: %8d LBN %8d %s\n",_2 fid,match_lbn,full_filename);L if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; if (full_flag) { J struct FH2DEF *header; /* Pointer to file header */1 header = &dir_buffer[j*512];a) dump_header(header);t }  found = 1; } elseh { if ( i, (valid_flag == 0) || K ( (valid_flag == 2) && (status == &DSKB_HDRINVFID) )  ) {]< sprintf(line,"FID: %8d LBN %8d %s\n",0 fid,match_lbn,filename);O if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;i found = 1;t }N }A } /* End of found a MATCH for the filename or LBN */iK if ( (found == 1) && /* We've found a match */cK (valid_flag == 1) && /* We want valid files only */ K (block[0] != 0xFFFFFFFF) && /* This is DIR /LBN */TK (block[1] == 0xffffffff) && /* ONLY 1 LBN specified */WK (lbn_count[0] == 0) /* ONLY 1 LBN specified */  ) return;= } /* End of one header, go and check one more */dA lbn = lbn + block_count; /* Time for another read... */t if (controlt_flag == 1) { short fid; controlt_flag = 0;& fid = lbn - index_lbn[i] +/ index_tot[i] - index_cnt[i] - } /* End of for (i=0, found=0 ..., finished all extents */- if (found==0) LIB$SIGNAL(&DSKB_NOFILES,0);t close_output();} @unsigned int read_blocks(int lbn, int block_count, char *buffer){l extern unsigned shortK disk_channel; /* Channel for Disk or File I/O */oK unsigned long status, /* VMS status return * ˿$DISKBLOCK055.DZHfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DIRECTORY.C;2XNI/cK iosb[2], /* VMS I/O status block */)K buffsize; /* QIO buffer size */_K const int function = IO$_READLBLK; /* VMS I/O function code */(L buffsize = 512*block_count; /* Buffer size for $QIO */J status = SYS$QIOW(0, /* Event Flag Number */J disk_channel, /* I/O channel */J function, /* I/O function code */J iosb, /* I/O status block address*/J 0, /* AST Address */J 0, /* AST Parameter */J buffer, /* P1, buffer address */J buffsize, /* P2, buffer size */J lbn, /* P3, LBN */J 0, /* P4, not used */J 0, /* P5, not used */J 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0]; $ if (!$VMS_STATUS_SUCCESS(status)) { return status; } return 1;} 4void get_name(struct FH2DEF *header, char *filename){pO struct FI2DEF *name; /* Pointer to Filename part of header */ 9 unsigned short i; /* Loop counter */aI name = (struct FI2DEF *) ( (short *)header + header->FH2$B_IDOFFSET );=, memcpy(filename,name->FI2$T_FILENAME,20);1 memcpy(filename+20,name->FI2$T_FILENAMEXT,66);5 for (i=0 ; (filename[i] != '\0') && (i<=89) ; i++)n1 if (filename[i] == ' ') filename[i] = '\0';n}],*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.C;2+,Z./ 4Wp-fJ0123KPWO5 6lޅd-7 8#u*9G HJ#include "diskblock.h"G#include /* for $CRELNM system service */G#include /* VMS privilege definitions */G#include /* for definition of VAXC$ESTABLISH */2/*************************************************2 * diskblock.c Main program for Diskblock *2 * *2 * This module includes initialisation, *2 * command parsing and the exit routine *2 * *3 *************************************************/ main(){Pextern struct DSKB_IO dskb_io[2]; /* Descriptions of two possible I/Os */P /* efns are filled in here... */Iextern unsigned long pid; /* PID of invoking process */extern unsigned short O ast_channel, /* I/O channel for handling ^T ast interrupts */O term_flag; /* 1 = SYS$OUTPUT is a terminal */Oextern struct dsc$descriptor_s help_logical; /* Library logical name */O$DESCRIPTOR(lnm$file_dev, "LNM$FILE_DEV"); /* Table to search for "" " */O$DESCRIPTOR(lnm$process, "LNM$PROCESS"); /* " " define "" " */Nint ast_iosb[2], /* I/O status block for ^T and ^C */N i; /* loop counter */Nconst int ast_mask[2] = {0,0x100004}, /* Character mask for ^C and ^T */N ast_function = IO$_SETCHAR|IO$M_OUTBAND, /* Function code for ^T */N contc_function = IO$_SETMODE|IO$M_CTRLCAST; /* Function code for ^C */Ovoid rms_flush_ast(int reqidt); /* Flushes output buffer every 15 seconds */Fextern int flush_efn; /* Event flag for MS Flush AST $SETIMR */Oextern int fifteen_secs[2]; /* VMS Quadword for 15 seconds */O$DESCRIPTOR(timbuf,"0 00:00:15"); /* 15 seconds for $ASCTIM */O$DESCRIPTOR(prompt, "DISKBLOCK> "); /* DISKBLOCK> prompt string */O$DESCRIPTOR(sys$input, "SYS$INPUT"); /* Terminal name for $ASSIGN */O$DESCRIPTOR(sys$output, "SYS$OUTPUT"); /* Terminal name for $GETDVI */Ounsigned long status, /* Return status from VMS system services */O iosb[2], /* I/O Status Block for VMS system services */A curpriv, /* Privileges of invoking process */O devclass; /* SYS$OUTPUT Device class */struct ITEM_LIST O itemlist[3]; /* Item List for $GETJPI & $GETDVI system services */G/**********************************************************************G * Establish a condition Handler *H **********************************************************************/ VAXC$ESTABLISH( handler );G/**********************************************************************G * Display the DISKBLOCK header messages *H **********************************************************************/ printf("\n\n");: printf(" DISKBLOCK V5.5\n");W printf(" Copyright (c) Digital Equipment Corp. 1995. All rights Reserved.\n\n");P printf(" This software can and WILL corrupt disks if it is mis-used,\n");P printf(" use it with care and back everything up before you start.\n\n");E printf(" Type HELP for instructions\n\n\n");G/**********************************************************************G * Use GETJPI to find PID and privileges of current process *H **********************************************************************/M itemlist[0].buffer_length = 4; /* Buffer length */M itemlist[0].item_code = JPI$_PID; /* Item required */M itemlist[0].address = &pid; /* Buffer address */M itemlist[0].retlen = 0; /* Length of data not wanted */! itemlist[1].buffer_length = 4;, itemlist[1].item_code = JPI$_CURPRIV;( itemlist[1].address = &curpriv;! itemlist[1].retlen = 0;D itemlist[2].buffer_length = 0; /* End of item list */! itemlist[2].item_code = 0;8 status = SYS$GETJPIW(0, 0, 0, &itemlist, &iosb, 0, 0);4 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];$ if (!$VMS_STATUS_SUCCESS(status))  {) LIB$SIGNAL(&DSKB_JPIERR,0,status,0); exit(0); } H/***********************************************************************H * Check that the current process has LOG_IO privilege *I ***********************************************************************/% if ((curpriv & PRV$M_LOG_IO) == 0)  { LIB$SIGNAL(SS$_NOLOG_IO); exit(0); } H/***********************************************************************H * Allocate two event flags for QIOs *H * and Initialise the two I/O buffer pointers to NULL *I ***********************************************************************/ for (i=0 ; i <= 1 ; i++) {E if (!$VMS_STATUS_SUCCESS(status = LIB$GET_EF(&dskb_io[i].efn))) {, LIB$SIGNAL(&DSKB_EFERR,0,status,0); exit(0); }  dskb_io[i].buffer = NULL; }< /********************************************************< * Find out if sys$output is a terminal, and set flag *= ********************************************************/# itemlist[0].buffer_length = 4;/ itemlist[0].item_code = DVI$_DEVCLASS;+ itemlist[0].address = &devclass;# itemlist[0].retlen = 0;# itemlist[1].buffer_length = 0;# itemlist[1].item_code = 0; status = SYS$GETDVI(? 0, /* Event flag number */? 0, /* Channel (not used) */? &sys$ou ͂$DISKBLOCK055.DZfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.C;2W{ tput, /* Device Name */? &itemlist, /* Item list address */? &iosb, /* I/O Status Block */? 0, /* AST address */? 0, /* AST param */? 0 /* NULL argument */ ); 5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];B if ( (!$VMS_STATUS_SUCCESS(status)) || (devclass != DC$_TERM) ) term_flag = 0; else term_flag = 1;H/***********************************************************************G * If help_logical is undefined then define it as DISKBLOCK *I ***********************************************************************/: status = SYS$TRNLNM(0,&lnm$file_dev,&help_logical,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {+ const char diskblock[] = "DISKBLOCK"; 5 itemlist[0].buffer_length = strlen(diskblock);/ itemlist[0].item_code = LNM$_STRING;. itemlist[0].address = &diskblock;% itemlist[0].retlen = 0; % itemlist[1].buffer_length = 0;% itemlist[1].item_code = 0; I status = SYS$CRELNM(0, &lnm$process, &help_logical, 0, &itemlist); }H/***********************************************************************H * Assign an IO channel to sys$input, this will be used for control_t *H * and control_c out of band AST handling *I ***********************************************************************/5 status = SYS$ASSIGN(&sys$input, &ast_channel,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {> LIB$SIGNAL(&DSKB_NOCON_T,0,&DSKB_NOTERMCHAN,0,status,0);> LIB$SIGNAL(&DSKB_NOCON_C,0,&DSKB_NOTERMCHAN,0,status,0); } elseE { /* Enable the out of band AST's for CONTROL_T and CONTROL_C */P status = SYS$QIOW(0, /* Event Flag Number */P ast_channel, /* I/O channel */P ast_function, /* I/O function code */P ast_iosb, /* I/O status block address */P 0, /* AST Address */P 0, /* AST Parameter */P &control_t, /* P1, Out of Band AST address */P ast_mask, /* P2, Out of Band char mask */P 0, /* P3, not used */P 0, /* P4, not used */P 0, /* P5, not used */P 0); /* P6, not used */< if ($VMS_STATUS_SUCCESS(status)) status = ast_iosb[0];' if (!$VMS_STATUS_SUCCESS(status))' LIB$SIGNAL(&DSKB_NOCON_T,0,status,0);P status = SYS$QIOW(0, /* Event Flag Number */P ast_channel, /* I/O channel */P contc_function, /* I/O function code */P ast_iosb, /* I/O status block address */P 0, /* AST Address */P 0, /* AST Parameter */P &control_c, /* P1, Control C AST address */P 0, /* P2, not used */P 0, /* P3, not used */P 0, /* P4, not used */P 0, /* P5, not used */P 0); /* P6, not used */< if ($VMS_STATUS_SUCCESS(status)) status = ast_iosb[0];' if (!$VMS_STATUS_SUCCESS(status))' LIB$SIGNAL(&DSKB_NOCON_C,0,status,0); } B/*****************************************************************B * Request an AST interrupt in 15 seconds. This will be used to *B * flush RMS buffers of output and log files every 15 seconds *C *****************************************************************/. status = sys$bintim(&timbuf,&fifteen_secs);$ if (!$VMS_STATUS_SUCCESS(status)) return status;= if (!$VMS_STATUS_SUCCESS(status = LIB$GET_EF(&flush_efn))) {) LIB$SIGNAL(&DSKB_EFERR,0,status,0); exit(0); } ? status=sys$setimr(flush_efn,fifteen_secs,rms_flush_ast,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) return status;H/***********************************************************************H * Accept a command from the User, Parse the command and dispatch it *I ***********************************************************************/ while(TRUE) {4 static const $DESCRIPTOR(line_param,"$LINE");P char line[1024]; /* Line read by cli$get_value */ # $DESCRIPTOR(line_desc,line); 4 status=cli$dcl_parse(0, &diskblock_commands, = get_input, get_input, &prompt);0 if (status == RMS$_EOF) diskblock_exit();7 if ($VMS_STATUS_SUCCESS(status)) cli$dispatch(); }/* End of while(TRUE) */}/* End of Main */H/***********************************************************************H * DISKBLOCK_EXIT: Check if the buffer has been modified if it has *H * and there is a drive selected then don't allow an exit. *H * Close any open logfile and report logfile name to user *I ***********************************************************************/void diskblock_exit(void){ extern unsigned short O modify_flag, /* 1 = I/O buffer has been modified */H access_flag, /* 1 = Selected drive/file has been accessed */O log_flag; /* 1 = Log file is open */ O extern struct FAB logfab; /* File attributes block */O extern struct NAM lognam; /* Name block */O unsigned int status; /* VMS Status return */ . if ( (modify_flag==1) && (access_flag==1) ) {3 LIB$SIGNAL(&DSKB_WR_OR_DES,0,&DSKB_BUFMOD,0); return; }  if (log_flag!=0) {& status = SYS$CLOSE(&logfab,0,0);' if (!$VMS_STATUS_SUCCESS(status))F LIB$SIGNAL(&DSKB_CLOSERR,3,lognam.nam$b_rsl,lognam.nam$l_rsa, logfab.fab$l_stv,0); log_flag = 0;E LIB$SIGNAL(&DSKB_LOGCLOSE,2,lognam.nam$b_rsl,lognam.nam$l_rsa); } exit(0);}.*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.COM;2+,\F./ 4N-fJ0123KPWO5 6a,7D!8u*9G HJ $ set noon"$! Command file to build DISKBLOCK$!/$! Sets dcl symbols CCQUALS and LINKQUALS as...$!=$! If DECC is installed then CCQUALS = "/DECC/STANDARD=VAXC"G$! If this is an Alpha system then add "/DEFINE=ALPHA" to CCQUALS $!M$! If this is a VAX without DECC then Linkquals includes the appropriate3$! linker options file, otherwise it is blank.$!K$! If P1 = DEBUG then add appropriate DEBUG qualifiers to both symbols$!$!!$! Then uses MMS to do the build.$!$ if (f$getsyi("CPU") .eq. 128)$ then<$ write sys$output "Setting symbols for Alpha compilation",$ ccquals == "/STANDARD=VAXC/DEFINE=ALPHA"$ linkquals == ""$ else&$ ! Find out if DECC is installed..."$ define /user sys$output _nla0:!$ define /user sys$error _nla0:$$ cc/decc sys$input /object=_nla0:main(){}L$! DCL-W-IVQUAL (or DCL-W-IVVERB) will be returned if DECC is not installed"$ result = $status .and. %xfffffN$! Make sure we have cleared any user mode logicals by  `$DISKBLOCK055.D\FfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.COM;2N~executing an image!!@!?$ search 'f$environment("procedure")' "search" /output=_nla0:7$ if (result .eq. %X38240) .OR. (result .eq. %X38090)$ thenB$ write sys$output "Setting qualifiers for VAXC compilation"$ ccquals == ""8$ linkquals == " diskblock_dir:diskblock.opt/opt,"$ elseF$ write sys$output "Setting qualifiers for VAX DECC compilation"($ ccquals == "/DECC/STANDARD=VAXC"$ linkquals == "" $ endif$ endif$!$ if "''P1'" .eqs. "DEBUG"$ then,$ Write sys$output "Compiling with /DEBUG",$ ccquals == "''ccquals'" + "/DEBUG/NOOPT"+$ linkquals == "/DEBUG" + "''linkquals'"$ endif$!'$ if f$trnlnm("diskblock_dir") .eqs. ""$ then+$ this_proc = f$environment("procedure").$ this_dev = f$parse(this_proc,,,"device")1$ this_dir = f$parse(this_proc,,,"directory")3$ define /job diskblock_dir 'this_dev''this_dir'$ endif$!&$ mms /descrip=diskblock_dir:diskblockC$! DCL-W-IVVERB (%X38090) will be returned if MMS is not installed $ result = $status .and. %xfffff$ if result .eq. %X38090 $ then C$ write sys$output "MMS not installed, compiling ALL sources..."4$ @diskblock_dir:diskblock_no_mms "''P1'" "''P2'"$ endif$!$ exit,*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.H;2+,!S./ 4O-fJ0123KPWO5 6,N[-7dl!8du*9G HJ2 /* diskblock.h Header file for diskblock */#ifndef __DISKBLOCK_DEFS_LOADED!#define __DISKBLOCK_DEFS_LOADED 1 #ifdef __DECC#define FIB_FID fib$w_fid#define FIB_ACCTL fib$l_acctl#else-#define FIB_FID fib$r_fid_overlay.fib$w_fid2#define FIB_ACCTL fib$r_acctl_overlay.fib$l_acctl #endifF#include "f11def.h" /* Files 11 definitions" */F#include /* Access control list entries */F#include /* Used for sys$shange_acl */F#include /* File attributes block */F#include /* CLI messages */F#include /* Character types e.g. isprint() */F#include /* Device Class definitions */F#include /* String Descriptors */F#include /* for $GETDVI system service */F#include /* FIB used by ACP QIOs */F#include /* QIO system service definitions */F#include /* GETJPI system service */F#include /* RMS data structures */#include F#include /* System Service return values */F#include /* Variable length argument list */F#include /* C I/O definitions */L#include /* For definition of $VMS_STATUS_SUCCESS */Mglobalref diskblock_commands; /* name of DCL command table */Mglobalref /* Messages in MESSAGES.MSG */ DSKB_ACLERR, DSKB_ADDRBIG, DSKB_ASNERR, DSKB_BADHEADER, DSKB_BLKMODIF, DSKB_BLKREAD, DSKB_BUFMOD, DSKB_BUFNOTMOD, DSKB_CHKCHANGED, DSKB_CHKINVALID, DSKB_CHKVALID, DSKB_CLOSERR, DSKB_CONTROL_C, DSKB_CONTROL_T, DSKB_COPYING, DSKB_CPYATTRIB, DSKB_CPYACL, DSKB_CREATED, DSKB_CREATERR, DSKB_DATABIG, DSKB_DESEL, DSKB_DISKSEL, DSKB_DSNERR, DSKB_DVIERR, DSKB_EFERR, DSKB_EXTFID, DSKB_FACTOR, DSKB_FID_FFFF, DSKB_FIDTOOBIG, DSKB_FILESEL, DSKB_FIRST100, DSKB_FLUSHTIMERR, DSKB_FORCEDERR, DSKB_FOUND, DSKB_GETERR, DSKB_INDEXFMAP, DSKB_HBLKINVCHK2, DSKB_HBLKINVCHK1, DSKB_HDRINVCHK, DSKB_HDRINVIDOFF, DSKB_HDRINVMPOFF, DSKB_HDRINVACOFF, DSKB_HDRINVRSOFF, DSKB_HDRINVSTRLEV, DSKB_HDRINVSTRVER, DSKB_HDRINVFID, DSKB_HDRINVMAP, DSKB_HOMEBLOCKERR, DSKB_INDXHDRERR, DSKB_INSVIRMEM, DSKB_INVBACKLINK, DSKB_INVFID, DSKB_INVNUMBER, DSKB_INVTIME, DSKB_JPIERR, DSKB_LASTBLOCK, DSKB_LASTFID, DSKB_LBNCOUNTERR, DSKB_LOGCLOSE, DSKB_LOGERROR, DSKB_LOGFILE, DSKB_NOBLOCK, DSKB_NOBLOCKS, DSKB_NOCON_C, DSKB_NOCON_T, DSKB_NOEXTHDR, DSKB_NOFID0, DSKB_NOFILENAME, DSKB_NOFILES, DSKB_NOINDEXF, DSKB_NOKB, DSKB_NOKT, DSKB_NOSEL, DSKB_NOTACCES, DSKB_NOTDISK, DSKB_NOTERMCHAN, DSKB_NOTFILE, DSKB_NOTFOR, DSKB_NOTMNT, DSKB_NOTOWNER, DSKB_NOVBN0, DSKB_NO_COUNT0, DSKB_NUMBIG, DSKB_NYI, DSKB_OPENERR, DSKB_PUTERR, DSKB_RDBADHEADER, DSKB_READERR, DSKB_RESTORED, DSKB_SEARCHDONE, DSKB_SEARCHING, DSKB_SKIPHDR, DSKB_SPAWNERR, DSKB_SPIRALREAD, DSKB_STRBIG, DSKB_STRTOOLONG, DSKB_WRTBADHEADER, DSKB_WRITERR, DSKB_WRTENAB, DSKB_WRTPROT, DSKB_WR_OR_DES;void attach(void), checksum(void), copy_file(void), deposit_buffer(void), deposit_string(void), deselect(void), directory(void), diskblock_exit(void), dump_buffer(void), examine_buffer(void), help_request(void), open_output(void), close_output(void), control_c(void), control_t(void), read_block(void), restore_buffer(void), rewrite_block(void), save_buffer(void), search_disk(void), select_disk(void), select_file(void), set_log(void), set_nyi(void), show_status(void), spawn(void), write_block(void);#define __struct variant_struct#define __union variant_unionunion ALPHA_INST{ unsigned long int longword; __struct /* PAL */ { unsigned palcode : 26 ; unsigned opcode : 6 ; } PAL_TYPE;$ __struct /* Floating Operate */ { unsigned Fc : 5 ; unsigned F_func : 11 ; unsigned Fb : 5 ; unsigned Fa : 5 ; unsigned pad1 : 6 ; } F_OPER_TYPE;# __struct /* Integer Operate */ { unsigned Rc : 5 ; unsigned I_func : 7 ; unsigned lit_flag : 1 ; unsigned SBZ : 3 ; unsigned Rb : 5 ; unsigned Ra : 5 ; unsigned pad2 : 6 ; } I_OPER_TYPE;0 __struct /* Integer Operate With Literal */ { unsigned pad3 : 13 ; unsigned literal : 8 ; unsigned pad4 : 11 ; } I_LITERAL_TYPE; __struct /* Branch */ { int br_displ : 21 ; unsigned pad5 : 11 ; } I_BRANCH_TYPE; __struct /* Memory */ { int mem_displ : 16 ; unsigned pad6 : 16 ; } MEMORY_TYPE;! __struct /* Memory Branch */ {! int mem_br_displ : 14 ;! unsigned mem_br_type : 2 ;! unsigned pad7 : 16 ; } MEMORY_BRANCH_TYPE;} ;,/* Routine to decode an Alpha Instruction */<void decode_inst(union ALPHA_INST *instruction, char *line);,/* Routine to add one character to a line */#void addchar(char *line, char add);8/* Routine to locate next Map extent in a file header */Nvoid map_extent(struct FH2DEF *buff, /* Buffer containing file header */N struct FM2DEF **map, /* input - previous map pointer */N /* output - current map pointer */N int *count, /* Count from current map pointer */N int *lbn, /* Starting LBN from current map */N short flag); /* 1 = return placement pointers */N  ~a$DISKBLOCK055.D!SfJ,[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.H;2O! /* 0 = return mapping pointers */7/* Routine to convert protection mask to ASCII text) */8void protect_text(char *text, unsigned short int mask); 8/* Routine to add a single character to a text string */#void addchar(char *line, char add);(/* Routines to dump formatted bufffer */ void dump_ascii(char *buffer)," dump_instructions(char *buffer),% dump_header(struct FH2DEF *header), dump_home(char *buffer),7 dump_numbers(unsigned char *buffer, short data_size);A/* Routine to extract FILENAME.EXT;VERSION part of file header */5void get_name(struct FH2DEF *header, char *filename); unsigned long, read_or_write( A char *buffer, /* Buffer to use */A short write_flag, /* 0 = READ, 1 = WRITE */B short rewrite_flag /* 1 = REWRITE */  ),1 read_header(char *buffer, int lbn),0 check_header(struct FH2DEF *buff),B fid_to_lbn(unsigned long fid, unsigned long *block),% print_line(char *line),# yes_no(char *prompt),+ fid_to_name(unsigned int fid,. char *full_filename,, unsigned int *lbn,6 unsigned short signal_flag), checksum_buffer(K unsigned char *buff, /* Address of buffer */K int message, /* TRUE = print status info */K int offset, /* # of bytes to checksum */K int deposit_flag /* TRUE = correct checksum */ ),> put_output(struct dsc$descriptor_s *out_string), get_input(O struct dsc$descriptor_s *in_string, /* Descriptor for returned string */O struct dsc$descriptor_s *prompt, /* Descriptor for prompt */O unsigned short *len /* Returned string length */ );)int handler( int *sigarr, int *mecharr );int get_integer (J struct dsc$descriptor_s *param, /* CLI Parameter name */J unsigned long max_data, /* maximum allowed value */J unsigned long *address /* Address for returned data */ ); int get_time (L struct dsc$descriptor_s *param, /* CLI Parameter name */L unsigned int *quadword /* Returned quadword date/time */ );struct FIB_DESC {O int length; /* Length of file information block */O struct fibdef *fib; /* Address of file information block */ };struct ITEM_LIST {. short int buffer_length;* short int item_code;( int address;' int retlen; };A/* dskb_io[] is used to maintain context information during */A/* SEARCH. The EFN and buffer fields are filled in by SELECT. */struct DSKB_IO {M int efn; /* Event Flag */M int block; /* Starting LBN/VBN */M int byte_count; /* Byte Count */ struct  { O unsigned short status; /* I/O completion status */O unsigned short bytes; /* No of bytes transferred*/O long pad; /* Pad to a quadword */M } iosb; /* call it an I/O status block */ M char *buffer; /* pointer to I/O buffer */ };#endif.*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2+,@S./ 4W-fJ0123KPWO56T<7$!8$u*9G HJ1 InstallationH To install DISKBLOCK you need to copy the kit to a directory on your 4 local system where you have 1500 blocks of quota.B Then type @SYS$UPDATE:VMSINSTAL DISKBLOCK dev:[dir] to install C diskblock. DISKBLOCK installation DOES NOT modify any VMS files. C After deleting all files except DISKBLOCK.EXE and DISKBLOCK.HLB$ it will take up about 400 blocks.E To use this help file from within DISKBLOCK you may either copy theD library to SYS$COMMON:[SYSHLP]DISKBLOCK.HLB or define logical name; DSKB_HLB to point to be dev:[dir]filename of the library.1 HELP3 DISKBLOCK is a low level disk block editing tool.J It can be used to read /modify /write LBNs on a disk or VBN's in a file.9 Type OVERVIEW at the Topic? prompt for more information 1 OverviewG DISKBLOCK is a tool for reading and writing Logical Blocks on a disk  or Virtual Blocks in a file.F Diskblock ingores all locking activity on the selected Disk or File.D There is a buffer which holds a copy of the block which you read, F you can modify the contents of this buffer using EXAMINE and DEPOSITI commands and then REWRITE it to the same block, WRITE it to a differentG block or SELECT a new disk or file and WRITE the buffer to any block.F When you SELECT a disk, diskblock will attempt to map the Index FileJ If it is successful then any command which requires an LBN (READ, WRITE,I COPY etc...) will also accept a FID and operate on the appropriate file? header. This will work even if the disk is mounted /FOREIGN.I There are commands to SAVE and RESTORE the buffer so that you can keep J a copy of the original block and undo changes if they do not work as you expect.H There is a CHECKSUM command to enable you to recalculate the checksums( for ODS2 file headers and home blocks.@ There is a DIRECTORY command which will find the header for a - file (even if the disk is mounted /foreign)H There is a COPY command which will enable you to treat any block on a L disk as a file header and copy the LBNs described by its mapping pointers 7 to a new file (even if the disk is mounted /foreign). C There is a SEARCH command which will search the entire disk/file E (or any range of blocks) for a particular string or integer or file header.; Because of its potential to corrupt disks you should onlyB use Diskblock in extreme desperation or on a disk which you have backed up.  - You need LOG_IO privilege to run DISKBLOCK.9 Type EXAMPLES at the Topic? prompt for more information 1 ExamplesE Search shows the use of the search command to locate a file header,7 and then to copy the file to a normally mounted disk.= This may be used even on a disk with a corrupted INDEXFILE.H Modify_disk shows the use of DISKBLOCK to repair a damaged home block.H Modify_MFD shows the use of DISKBLOCK to change the file attributes of [000000]000000.DIR= Undelete_file shows the use of DISKBLOCK to undelete a file2 SearchF In this example DISKBLOCK is used to find a file on a corrupted disk> and then to copy the file to the users SYS$SCRATCH directory $ RUN SYS$SYSTEM:DISKBLOCK* DISKBLOCK V5.5H Copyright (c) Digital Equipment Corp. 1995. All rights Reserved. $ MOUNT /FOREIGN $1$DUA42# DISKBLOCK> SELECT $1$DUA42 /NOMAP' DISKBLOCK> SEARCH /HEADER=X.EXT /FULLR %DSKB-I-SEARCHING, Searching blocks 0 - 2376152 for HEADER "X.EXT;*" at 13:23:45! LBN: 1188943, Filename: X.EXT;2: FID: 1032, SEGNUM: 0, CREDATE: 19-MAY-1994 01:30:09.762 %DSKB-I-SEARCHDONE, Search completed at 13:44:10& DISKBLOCK> DUMP /FILE /BLOCK=11889437 ... Check that this is the correct file header....... DISKBLOCK> COPY 1188943; %DSKB-I-CREATED, Created file DUA0:[RANCE]COPY_FILE.DAT;1< %DSKB-I-COPYING, Copying 214 blocks starting at LBN 113124: %DSKB-I-COPYING, Copying 24 blocks starting at LBN 10456S %DSKB-I-CPYACL, 92 Bytes of ACL information copied to DUA0:[RANCE]COU$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2W" PY_FILE.DAT;1W %DSKB-I-CPYATTRIB, File attributes successfully copied to DUA0:[RANCE]COPY_FILE.DAT;1 2 Modify_diskE In this example a backup copy of the home block is used to repair a corrupted primary home block. $ RUN SYS$SYSTEM:DISKBLOCK* DISKBLOCK V5.5H Copyright (c) Digital Equipment Corp. 1994. All rights Reserved.$ DISKBLOCK> MOUNT /FOREIGN $2$DUA22E DISKBLOCK> SELECT $2$DUA22 ; Select the problem driveJ DISKBLOCK> READ 2 ; Read backup copy of HomeblockE DSKB-I-BLKREAD, Block 2 (%X00000002) of _$2$DUA22 successfully read( DISKBLOCK> HELP ODS2 HOME HOMELBN J .......................... ; Find size and offset of field8 DISKBLOCK> DEPOSIT 0 1 ; New HOMELBN8 DISKBLOCK> DEPOSIT/WORD 16 2 ; New HOMEVBN= DISKBLOCK> CHECKSUM /HOME /DEPOSIT ; Modify checksumsE %DSKB-I-CHKCHANGED, Checksum has been changed from %X289B to %X3F9BE %DSKB-I-CHKCHANGED, Checksum has been changed from %X5136 to %X7F36? DISKBLOCK> DUMP /HOME ; See if it looks OK .........................G DISKBLOCK> WRITE 1 ; Write to primary homeblockK %DSKB-I-BLKMODIF, Block 1 (%X00000001) of _$2$DUA22 successfully modified 2 Modify_MFDK In this example the ownership of the MFD of a disk is changed to be [1,4] $ RUN SYS$SYSTEM:DISKBLOCK* DISKBLOCK V5.4H Copyright (c) Digital Equipment Corp. 1994. All rights Reserved.I DISKBLOCK> SELECT DUA2:/OVER ; Allow writes to mounted diskG DISKBLOCK> READ /FID=4 ; Read header for 000000.dirK DSKB-I-BLKREAD, Block 273590 (%X00042CB6) of _NODE$DUA2 successfully read3 FID: 4 LBN 273590 [000000]000000.DIR;1B DISKBLOCK> HELP ODS2 FILE_HEADER ; Check field for ownerC DISKBLOCK> DEPOSIT 60 %X00010004 ; CHANGE FH2$L_FILEOWNER DISKBLOCK> rewrite /checksumC%DSKB-I-CHKCHANGED, Checksum has been changed from %XCC5D to %XCC5AG%DSKB-I-BLKMODIF, Block 273590 (%X00042CB6) of _DINCY$DUA0 successfullymodified2 Undelete_fileJ In this example a file on an ODS2 mounted disk is undeleted by patching  the file header $ RUN SYS$SYSTEM:DISKBLOCK* DISKBLOCK V5.3H Copyright (c) Digital Equipment Corp. 1991. All rights Reserved." DISKBLOCK> SELECT /OVER $1$DUA2:* DISKBLOCK> DIRECTORY MYFILE.DAT /DELETED8 FID: 6998 LBN 273600 [RANCE.DAT]MYFILE.DAT;1: DISKBLOCK> read /fid=6998 ! Read the file headerJ %DSKB-I-BLKREAD, Block 273600 (%X00042CC0) of _$1$DUA2 successfully readB %DSKB-W-RDBADHEADER, Invalid File Header, FID: 6998, LBN: 273600I -DSKB-E-HDRINVFID, FH2$W_FID_NUM (byte 8) is 0, could be a deleted fileF DISKBLOCK> EXAM 52 ! Check current file characteristics@ DISKBLOCK> DEPOSIT 52 0 ! Clear bit 15 (FH2$V_MARKDEL)9 DISKBLOCK> DEPOSIT /WORD 8 6998 ! Write the correct FID; DISKBLOCK> CHECKSUM /DEPOSIT ! Create a valid checksumE %DSKB-I-CHKCHANGED, Checksum has been changed from %X5327 to %XAF62C DISKBLOCK> DUMP /FILE ! Check that file header is validH DISKBLOCK> REWRITE ! Write file header back to INDEXF.SYSM %DSKB-I-BLKMODIF, Block 1000 (%X000003E8) of _$1$DUA2 successfully modified8 Now you need to Dismount the disk, mount it again and 7 $ ANAL /DISK /REPAIR should put the file in [SYSLOST]1 New_Features2 V4.0_New_FeaturesC SELECT /FILE allows you to select a file and then do virtual I/O.E This can be useful for writing to a file which is locked by anotherJ user, or for searching a large file for a text string or Longword value.> Modifications made by Burnace Leung to create DSKBLK_V3 have? been included as COPY_FILE and DIRECTORY. See EXAMPLE SEARCH? for an example of copying a file from a foreign mounted disk.@ READ/FID has been added to enable you to specify a File ID and read the corresponding LBN.< A /CHECKSUM qualifier has been added to the write command.6 This makes life simpler when modifying file headers.# A number of bugs have been fixed.2 V4.1_new_featuresD There are only three very minor differences between DISKBLOCK V4.0 and DISKBLOCK V4.1.* The handling of HELP is now more robust.8 The search command can now be cancelled by typing a ^C0 DISKBLOCK can now be installed with VMSINSTAL.2 V5.0_New_FeaturesF Diskblock V5 has been totally re-written in C (it used to be Macro).= There are major improvements in the area of error handling,B especially in the handling of disk errors during READ and SEARCHA commands and in the validation of Home blocks and file headers.D Control C and Control T handling now work during Directory as well as search operations.= There has been a syntax change for READ /FID and WRITE /FID4 There are a number of new commands and qualifiers. 3 SET_LOGJ The SET LOG command causes ALL diskblock output to be sent to a log file as well as to the terminal 3 SET_PAGEG The SET PAGE command causes diskblock output to pause every screenful, and prompt with "Type a to continue". 3 REWRITEB The REWRITE command allows a block to be written back to the LBNG it was read from to reduce the chance of mis-typing the block number. 3 DIRECTORYJ The DIRECTORY command now displays FULL file specification, FID and LBN.C DIRECTORY/FID has been added to convert a FID number to filename.D DIRECTORY/LBN has been added to find the file using any given LBN.E The performance of the DIRECTORY command has been greatly improved.3 /FORCED_ERRORF There is a /FORCED_ERROR qualifier to WRITE and REWRITE which allowsG a block to be written with the forced error flag set. USE THIS WITH E EXTREME CAUTION - IF YOU DON'T UNDERSTAND WHAT IT MEANS THEN DON'T 9 USE IT!!!! 3 CHECKSUM/HOMEE The checksum command now takes a /HOME qualifier which causes it to8 check or modify BOTH of the checksums in a home block. 3 COPY/BUFFERA There is a /BUFFER qualifier to COPY_FILE which allows the mainC read/write buffer to be the file header of the file to be copied.G This enables you to modify the header without writing the input disk.3 /FIDF This qualifier to READ and WRITE now requires the fid as a qualifierI value (e.g. READ /FID=1000) rather than as a parameter (READ /FID 1000)@ This has been done to be consistent with DIR/FID and COPY/FID.2 V5.1_New_Features6 V5.1 has two minor bug fixes and three new features. Bug_fixesD DISKBLOCK> CHECKSUM/HOME/DEPOSIT now correctly sets both checksums? DISKBLOCK> DIR /LBN=0 now correctly identifies the INDEXF.SYS New_features DISKBLOCK> SET WRITE DISKBLOCK> SET NOWRITEB These commands enable and disable writing the selected disk/file DISKBLOCK> DIR ... /VALID_ONLY> This qualifier causes invalid file headers to be ignored and= DIR /LBN for a single LBN will finish after a single match.= The diskblock help library no longer has to be in SYS$HELP,) $ DEFINE DSKB_HLB dev:[dir]filaneme.HLB to access the help library2 V5.2_New_Features3 V5.2 has the following bug fixes and new features9 Diskblock now works on both OpenVMS VAX and OpenVMS AXPA DUMP /HOME has been added to display the buffer as a home block8 DUMP /HEADER has been added as a synonym for DUMP/FILED SEARCH/HEADER is a new command to find blocks that look like validC file headers and report the LBN and filename. It is NOT the sameG as the directory command since it does not use the INDEXF.SYS mapping" pointers to locate file headers./ EXAMINE/TIME and DEPOSIT/TIME have been added> COPY now propagates the file owner and protection as well as@ file characteristics and record attributes. It still does not propagate ACLs.? DISKBLOCK no longer issues a SHOW command every time you do a? select. You may issue the SHOW command yourself if required.? A memory leak has been fixed that lost TRACK_SIZE * 512 bytes$ every time a new disk was selected@ The page length was being incorrectly handled if a string withG no line feeds (or more than one line feed) was sent to the terminal,  this has now been fixed2 V5.3_New_Features% V5.3 has the following new features> FILL command fills the read write buffer with a data patternD Many new qualifiers to the Directory command allow file selections to be made.8 /SELECT=SIZE fM~$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2W<inds files above or below a certain size/ /BY_OWNER finds files with a particular owner# /DELETED finds ONLY deleted files0 /BACKFID finds files in a particular directory8 /BEFORE /SINCE /BACKUP /CREATED /EXPIRED and /MODIFIED< allow selection of files based on dates in the file header2 V5.4_New_Features4 V5.4 has the following new features and bug fixes.C DIRECTORY /PLACEMENT finds files with placement mapping pointersG SAVE and RESTORE now use the /BLOCKS=(START,END,COUNT) qualifier to H save and restore any contiguous range of blocks on the selected disk or file.G DUMP can now use the /BLOCK and /FID qualifiers to dump a formatted F block from the disk without having to overwrite the main read write buffer.E SEARCH /HEADER has a new switch /FULL which gives a second line ofF information for each header found showing Extension Segment number, Creation Date and FID.I Improvements have been made to the handling of disk read errors during DIRECTORY commands.L The default for a SELECT command has been changed from /WRITE to /NOWRITEI A potential hang caused by the use of the same Event flag at both AST % and process levels has been fixed.H An access violation during Examine commands on Alpha systems has been fixed.H Incorrect numeric and UIC displays from dump commands have been fixed2 V5.5_New_FeaturesJ The copy command now copies ACLs as well as other file characteristics.G The copy command now uses the filename from the input file header asH the default output file name. The default output directory is still  SYS$SCRATCH;E A problem which caused incorrect display of some data values from @ the dump command on OpenVMS Alpha systems has been corrected.C A problem which caused incorrect display of data values from theF EXAMINE /OCTAL command on OpenVMS Alpha systems has been corrected.1 SELECT: Use the SELECT command to select a new drive or file for; reading and writing. Before selecting a drive it must be? mounted foreign (unless you specify the /OVERRIDE qualifier).> SELECT automatically DESELECTS any previously selected drive% or file before selecting a new one.G By default LBN 1 (HOME BLOCK LBN) will be read to locate the primary @ index file header. If this fails because of hardware error orK corrupted home block then index file retrieval pointers will not be read. 2 Parameters device_name. Specifies the name of the disk to be selected file_name5 Specifies the name of the file to be selected (requires SELECT/FILE)2 Command_Qualifiers/FILEF Use this qualifier to enable you to perform Virtual I/O to a single D file on an ODS2 mounted disk. This allows you to use DISKBLOCK asC a utility somewhere between Patch and Dump, it will allow you to I modify the contents of a file without taking out RMS locks - even when , someone else has the file open and locked. /OVERRIDED Use the /OVERRIDE qualifier to enable you to read and write a diskE that is not mounted foreign. Use even more extreme care when doing@ this as you could cause great damage to the VMS file system by, modifying disks that are normally mounted.8 This qualifier cannot be used with the /FILE qualifier/NOMAPE Use this qualifier to prevent DISKBLOCK from reading the Home Block$ and Index File retrieval pointers.8 This qualifier cannot be used with the /FILE qualifier/HOMELBN< Use this qualifier to specify an alternate Home Block LBN.C DISKBLOCK will read this alternate HOMELBN, validate its contentshE and use it to locate the Index File Header. The Index File mappingL Pointers will then be read. 8 This qualifier cannot be used with the /FILE qualifier< This qualifier cannot be used with the /INDEXLBN qualifier /INDEXLBNKC Use this qualifier to specify an alternate Index File Header LBN.pC DISKBLOCK will read this LBN, validate its contents and read the S index file mapping pointers.8 This qualifier cannot be used with the /FILE qualifier8 This qualifier cannot be used with the /HOME qualifier> If you use the qualifier /INDEXLBN you must also use /FACTOR/FACTOR D If you use the /INDEXLBN qualifier then Diskblock will not read a D Home Block, this means that the cluster size and index file bitmapC size are not available. You must therefor specify a FACTOR whichn8 Diskblock can use to map File IDs to Indexfile VNBs.  F This factor should be (CLUSTER_SIZE * 4) + (Index File Bitmap Size) F If you select an incorrect value then Diskblock will translate FIDs  to LBNs incorrectly./WRITE@ Select /WRITE causes DISKBLOCK to operate in READ / WRITE modeC the WRITE and REWRITE commands can be used to modify the selectedk DISK or FILE.aD Select /NOWRITE causes DISKBLOCK to operate in READ ONLY mode, theI selected disk or file can be READ or SEARCHED but the WRITE and REWRITE commands will return an error. The default is SELECT /NOWRITE See also SET WRITE 2 Examples  DISKBLOCK> SELECT $2$DRA2:t1 DISKBLOCK> SELECT SYS$SYSTEM:SYSDUMP.DMP /FILEr' DISKBLOCK> SELECT $2$DUS0: /OVERRIDEn& DISKBLOCK> SELECT DISK$USER2 /NOMAP. DISKBLOCK> SELECT MYNODE$DUA1: /HOMELBN=nnn3 DISKBLOCK> SELECT DRA3: /INDEXLBN=nnn /FACTOR=85k 1 DESELECTF Use the DESELECT command to free a drive or file previously selectedF with a select command, this may help to prevent accidentally writingG to a drive/file %that you have finished with. An implicit DESELECT ise9 performed for you whenever you SELECT a new drive/file.eF Diskblock will not allow you to exit if the buffer has been modifiedD and there is still a Drive selected, you should Deselect the drive before exiting.g DISKBLOCK> DESELECTe1 READB The read command is used to transfer data to Diskblocks internalJ 512 byte buffer. You must SELECT a drive or file before a read command.6 You can read a Logical Block from the selected disk.* Or a file header from the selected disk., Or a Virtual Block from the selected file./ You must specify a Block Number or a File ID.d@ The default radix for the Block is decimal but you may use the< %X or %O operators to specify a Hex or Octal block number.G When you read a block the current contents of the buffer will be lostE If you require the current buffer contents then you should SAVE the ' bufffer before reading another block.l 2 Parameter  Block_numberC Specifies the LBN of the block to be read from the selected drivef; or the VBN of the block to be read from the selected fileo2 Command_Qualifiers/FID? Use the command READ /FID to read an LBN from a disk when youI= know the File ID of the file whose header you want to read..= This command will only work if you have read the index fileC+ mapping pointers with the SELECT command.CF The FID will be translated to an LBN and the appropriate file headerD will be read in to the buffer, the buffer will then be checked to B ensure that the file header is valid and diagnostic messages may be issued. See also DIRECTORY /FID< The syntax for this command has changed with DISKBLOCK V5. The format is now...  DISKBLOCK> READ /FID=100041 WRITE- See also REWRITE7 Use the write command to write the 512 byte buffer toi( A Logical Block on the selected drive,) Or a File Header on the selected drive,t* Or a Virtual Block in the selected file./ You must specify a Block Number or a File ID.;@ The default radix for the Block is decimal but you may use the< %X or %O operators to specify a Hex or Octal block number.> You must SELECT a drive or file before issuing this command. DISKBLOCK> WRITE %xFF & DISKBLOCK> WRITE /CHECKSUM /FID=1004 2 Parameter  Block_numberD Specifies the LBN of the block to be written on the selected drive< or the VBN of the block to be written to the selected file2 Command_Qualifiers /FORCED_ERRORbE This switch will cause the block to be written to the disk with thepG forced error flag set. USE THIS WITH EXTREME CAUTION - IF YOU DON'T s0 UNDERSTAND WHAT IT MEANS THEN DON'T USE IT!!!! G The effect of this flag may depend on the type of disk, on DSA disks eF it will cause a forced error condition when the block is read again,* the correct data will still be returned. F On some SCSI disks it will cause a parity error to be generated when/ the block is read and NO DATA to be returned.9% DISKBLOCK> WRITE /FORC3D\$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2WO"+ED_ERROR 100sJ DO NOT USE THIS SWITCH UNLESS YOU HAVE A VERY GOOD REASON AND YOU REALLYH UNDERSTAND WHAT YOU ARE DOING, IT HAS BEEN INCLUDED SINCE I NEEDED IT E FOR TESTING DISKBLOCK AND I HAVE VERY OCCASSIONALLY FOUND A USE FOR-8 A DISK THAT GENERATES HARDWARE ERRORS WHEN IT IS READ. /CHECKSUM B Use this command when the block you are writing is an ODS2 file D header. The block checksum will be caculated and then written to C the last word of the buffer. Then the WRITE function will write p& the buffer back to the selected LBN. See also CHECKSUM /DEPOSIT /FID? Use the command WRITE /FID to write an LBN on a disk when you > know the File ID of the file whose header you want to write.= This command will only work if you have read the index file + mapping pointers with the SELECT command.LD Diskblock will first verify that the buffer contains a valid file F header, if not then a diagnostic message will be issued and you willH be asked if you wish to continue. It will then convert the FID to theD LBN of the corresponding file header and write the header to disk.< The syntax for this command has changed with DISKBLOCK V5. The format is now...  DISKBLOCK> WRITE /FID=234 1 REWRITEhB Use the rewrite command to write the 512 byte buffer back to theB last block read or written. You do not need to specify a block number.RA You must SELECT a drive or file and then read or write a block Y before issuing this command.F To see the block that would be used for a rewrite command issue the  SHOW command.t DISKBLOCK> REWRITE DISKBLOCK> REWRITE /CHECKSUM" DISKBLOCK> REWRITE /FORCED_ERROR2 Command_Qualifiers /FORCED_ERRORrE This switch will cause the block to be written to the disk with thesG forced error flag set. USE THIS WITH EXTREME CAUTION - IF YOU DON'T u0 UNDERSTAND WHAT IT MEANS THEN DON'T USE IT!!!! G The effect of this flag may depend on the type of disk, on DSA disks F it will cause a forced error condition when the block is read again,* the correct data will still be returned. F On some SCSI disks it will cause a parity error to be generated when/ the block is read and NO DATA to be returned.>J DO NOT USE THIS SWITCH UNLESS YOU HAVE A VERY GOOD REASON AND YOU REALLYH UNDERSTAND WHAT YOU ARE DOING, IT HAS BEEN INCLUDED SINCE I NEEDED IT E FOR TESTING DISKBLOCK AND I HAVE VERY OCCASSIONALLY FOUND A USE FORR8 A DISK THAT GENERATES HARDWARE ERRORS WHEN IT IS READ. /CHECKSUM B Use this command when the block you are writing is an ODS2 file D header. The block checksum will be caculated and then written to C the last word of the buffer. Then the WRITE fucntion will write n& the buffer back to the selected LBN. See also CHECKSUM/DEPOSITV 1 COPY_FILEi (See also EXAMPLE SEARCH)CJ Copy_file will copy a file from a FOREIGN mounted or corrupted disk, as $ well as from an ODS2 mounted disk.H Diskblock will first verify that the block or buffer contains a valid G file header, if not then a diagnostic message will be issued and you s( will be asked if you wish to continue.B The default output directory is SYS$SCRATCH: The default output0 filename is the name of the file being copied.@ NOTE that the copy will take place using the mapping pointers B in the file header, if the file header is corrupt then this may " create a VERY large output file.E After the file data has been copied the File and Record attributes,sA the File Owner UIC and File Protection will be copied from the aH original file header to the new file header. The Access Control List G (ACL) from the input file header will then be copied to the new file.i C Use of this command does not modify the normal DISKBLOCK 512 byteg read / write buffer.E DISKBLOCK> COPY_FILE /OUTPUT=abcd.dmp %x90A12 ! LBN of file headerfE DISKBLOCK> COPY /FID=1234 ! FID of file headerq DISKBLOCK> COPY /BUFFER 2 Command_Qualifiers/OUTPUTbH Use this switch to specify the filename of the NEW file to be created./FID@ Use the command COPY /FID to copy a file when you know the FID@ but not the LBN of the file header. The fid will be converted4 to an LBN and the appropriate header will be read.= This command will only work if you have read the index filep+ mapping pointers with the SELECT command. < The syntax for this command has changed with DISKBLOCK V5. The format is now...  DISKBLOCK> COPY_FILE /FID=234t/BUFFER@ Use the command COPY /BUFFER when the file header for the file< you want to copy is already in the main read/write buffer.> This enables you to read a file header from disk, modify it B and then use the modified header to copy the file without having9 to write the modified header back to the original disk. 1 DIRECTORYUI DIRECTORY accepts a filename including the * and % wildcard characters. J (but excluding any [, ] or directory specification) and displays the FIDK and LBN of the file header and the FULL FILENAME (including directories).h F It will work on ODS2 mounted or foreign mounted disks so long as the4 index file has been mapped with the SELECT commandG Once the header has been read the Backlink in the file header will beoF used to find the directory name, up to 8 backlinks will be followed F until 000000.DIR is located and the full filename will be displayed.9 This command does not modify the main read/write buffer! DISKBLOCK> DIRECTORY [filespec]n 2 Parametera filespecD Specifies the file(s) to be listed. * and % wildcards are allowed8 Directory and/or device specifications are not allowed2 Command_Qualifiers/FID /FID = nnnK= Use DIR /FID to display the filename associated with a FID.  DISKBLOCK> DIRECTORY /FID=1000B FID: 1000 LBN: 1189345 [RANCE.SUBDIR.TEMP]TEMPFILE.EXT;23 See also READ /FID/LBN /LBN=(nnn[,...])AD Use DIR /LBN to find which file maps a particular LBN on the disk.J Diskblock will read the entire INDEX File and check the mapping pointersI in all file headers to locate the file(s) that map(s) the given LBN(s). H Diskblock will continue scanning even after it finds a match to enableH the indentification of all pointers to multiply allocated blocks. You9 can abort the search with a Control C (^C) at any time.hD If an invalid file header maps the lbn then an error message will 9 proceed the display of the filename. (See DIR /VALID).sG You may specify multiple LBNs on a single command line in three ways,r; DIRECTORY /LBN=(nnn,mmm,xxx,yyy) for multiple single LBNso? DIR /LBN=nnn /COUNT=xxx for a single contiguous range of LBNseC DIR /LBN=(nnn,mmm...) /COUNT=(xxx,yyy...) for many ranges of LBNseD The index file will only be scanned ONCE for each command so it isH much more efficient to form a single complex command with all the LBNsF you are interested in than to specify them one at a time in separate commands. /COUNT /COUNT=(nnn[,...]) B This switch can only be used in conjunction with DIRECTORY /LBN.= For the command DIR /LBN=x /COUNT=m all files that map LBNst+ in the range x to x+m-1 will be reported. A For the command DIR /LBN=(x,y) /COUNT=(m,n) all files that map )C LBNs in the ranges (x to x+m-1) and y to y+n-1) will be reported)w6 e.g. DIR /LBN=10 /COUNT=10 will match LBNs 10 to 195 DIR /LBN=(100,200) /COUNT=(10,20) will match n4 LBNs (100 to 109) and LBNs (200 to 219)/OUTPUTe /OUTPUT=filespec@ Use the /OUTPUT qualifier to cause the output to be written to= a file instead of to the terminal. The default filespec isn SYS$SCRATCH:DISKBLOCK.LIS./VALIDJ If the /VALID qualifier is specified then only matching files with validK file headers will be displayed. Any invalid file headers will be ignoreddG If /LBN and /VALID are both specified and there is only a SINGLE LBN iH specified then the scan will stop after a single valid match has been  found./SELECTT /SELECT=(keyword[,...])D The /SELECT qualifier has identical syntax and meaning to the DCL  command DIRECTORY/SELECT/ DISKBLOCK> DIRECTORY /SELECT=SIZE=MINIMUM=nnnO< Only report files with a size greater than or equal to nnn/ DISKBLOCK> DIRECTORY/ SELECT=SIZE=MAXIMUM=mmmi9 Only report files with a size less than or equal to nnnw= DISKBLOCK> DIRECTORY /SELECT=SIZE=(MINIMUM=nnn,MAXIMUM=mmm)d@ Only report files with a size greater than or equal to nnn AND less than or equal to mmme /BY_OWNERi /BY_OWNER=UICG Thn$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2W"<e /BY_OWNER qualifier enables you to find files owned by a specificm> UIC or rights identifier. Wild card UICs are not supported.( DISKBLOCK> DIRECTORY /BY_OWNER=[23,45]( DISKBLOCK> DIRECTORY /BY_OWNER=[RANCE]- DISKBLOCK> DIRECTORY /BY_OWNER=[USER,RANCE]x( DISKBLOCK> DIRECTORY /BY_OWNER=PROJECT/DELETEDK The /DELETED qualifier can be used to locate the headers of DELETED files I on the disk. If you use this qualifier then ONLY deleted files will befH reported, and the error message saying that this may be a deleted file will be suppressed DISKBLOCK> DIRECTORY /DELETED - DISKBLOCK> DIRECTORY /BACKLINK=nnn /DELETEDS* DISKBLOCK> DIRECTORY VITAL.FILE /DELETED/BACKFIDG Only reports files with a particular FID in the file header BACK FID.hG The BACK FID is the file id of the directory to which the file header is pointing= The file id of a directory file can be found by DUMP/HEADERrB of the directory file (either from DCL or from within DISKBLOCK)J This qualifier can be used to locate all files in a particular directoryJ It can be particularly useful in conjunction with the /DELETED qualifier= to locate all files that have been DELETED from a directoryo- DISKBLOCK> DIRECTORY /BACKLINK=nnn /DELETEDO /PLACEMENTH Only reports files which have placement information specified in their mapping pointers.  /SINCE /SINCE=time: Selects only those files dated after the specified time.L You must specify one of the following qualifiers with the /SINCE qualifierF to indicate the time attribute to be used as the basis for selection, /BACKUP /CREATED /EXPIRED or /MODIFIED! The time should be specified ast /SINCE=01-jan-1990 /SINCE=01-JAN-1990M /SINCE="01-JAN-1990 03:42:00.00" <-- NOTE: MUST BE UPPER CASE and QUOTEDt/BEFOREh /BEFORE=timec; Selects only those files dated before the specified time.aM You must specify one of the following qualifiers with the /BEFORE qualifierpF to indicate the time attribute to be used as the basis for selection, /BACKUP /CREATED /EXPIRED or /MODIFIED! The time should be specified asa /BEFORE=01-jan-1990  /BEFORE=01-JAN-1990aN /BEFORE="01-JAN-1990 03:42:00.00" <-- NOTE: MUST BE UPPER CASE and QUOTED q/BACKUPcB Modifies the time value specified with the /BEFORE or the /SINCEA qualifier. The /BACKUP qualifier selects files according to theiD dates of their most recent backups. This qualifier is incompatibleC with the following qualifiers that also allow you to select fileseB according to time attributes: /CREATED, /EXPIRED, and /MODIFIED./CREATEDB Modifies the time value specified with the /BEFORE or the /SINCE@ qualifier. The /CREATED qualifier selects files based on their< dates of creation. This qualifier is incompatible with theD following qualifiers that also allow you to select files according7 to time attributes: /BACKUP, /EXPIRED, and /MODIFIED.K/EXPIREDB Modifies the time value specified with the /BEFORE or the /SINCED qualifier. The /EXPIRED qualifier selects files according to theirA expiration dates. (The expiration date is set with the SET FILE C /EXPIRATION_DATE command.) The /EXPIRED qualifier is incompatibleOC with the following qualifiers that also allow you to select filesc7 to time attributes: /BACKUP, /CREATED, and /MODIFIED.s /MODIFIEDiB Modifies the time value specified with the /BEFORE or the /SINCE? qualifier. The /MODIFIED qualifier selects files according toi? the dates on which they were last modified. This qualifier iseC incompatible with the following qualifiers that also allow you tolC select files according to time attributes: /BACKUP, /CREATED, and/ /EXPIRED.D/FULLtL Outputs a formatted dump of the file header for each matching file found 2 Examples! DISKBLOCK> DIR IMPORTANT*.*FILEeD FID: 2045 LBN: 1023456 [DIR.SUBDIR]IMPORTANT_3.ANY_FILE;1H FID: 31927 LBN: 2220459 [DIR.SUB.SUB]IMPORTANT.ANOTHER_FILE;14 DISKBLOCK> DIR *.* /OUTPUTE %DSKB-I-CREATED, Created file DISK$USERS3:[RANCE.TEMP]DISKBLOCK.LIS G %DSKB-I-LASTFID, Just read FID 2883 at 16:23:08 <-- Control T typedM DISKBLOCK>  DISKBLOCK> DIR /FID=2045D FID: 2045 LBN: 1023456 [DIR.SUBDIR]IMPORTANT_3.ANY_FILE;1 DISKBLOCK> DIR /LBN=10008 FID: 7671 LBN: 370067 [RANCE.SUBDIR]FILE.EXT;2D %DSKB-W-RDBADHEADER, Invalid File Header, FID: 15499, LBN: 1203844I -DSKB-E-HDRINVFID, FH2$W_FID_NUM (byte 8) is 0, could be a deleted filei9 FID: 15499 LBN: 1203844 [RANCE]DELETED_FILE.TMP;1p! DISKBLOCK> DIR /LBN=1000 /VALIDo8 FID: 7671 LBN: 370067 [RANCE.SUBDIR]FILE.EXT;2 DISKBLOCK> DIR /BACKLINK=2301f1 FID: 7671 LBN: 370067 [RANCE]FILE.EXT;2sD %DSKB-W-RDBADHEADER, Invalid File Header, FID: 15499, LBN: 1203844I -DSKB-E-HDRINVFID, FH2$W_FID_NUM (byte 8) is 0, could be a deleted files1 FID: 15499 LBN: 1203844 [RANCE]FILE.EXT;1C1 FID: 20111 LBN: 370067 [RANCE]FILE.EXT;4a1 FID: 108520 LBN: 2045192 [RANCE]FILE.EXT;3r( DISKBLOCK> DIR /BACKLINK=2301 /DELETED1 FID: 15499 LBN: 1203844 [RANCE]FILE.EXT;1tC DISKBLOCK> DIR /VALID /BACKLINK=2301 /MODIFIED /SINCE=01-JAN-1993c1 FID: 20111 LBN: 370067 [RANCE]FILE.EXT;4o& DISKBLOCK> DIR /LBN=(1000,1200,5000), DISKBLOCK> DIR /LBN=1000 /COUNT=500 /VALIDF This command will locate file headers that map any LBNs in the rangeF 1000, 1001, 1002, ... 1498, 1499. It will continue scanning to the G end of INDEXF.SYS even after all matches have been found and multiply G allocated blocks will be reported against all valid headers. InvalideA or deleted headers which map any of these LBNs will be ingored.D= DISKBLOCK> DIRECTORY /LBN=(1000,2000,3000) /COUNT=(10,10,5) J This command will locate file headers that MAP any of the following LBNs< 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009< 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009$ 3000, 3001, 3002, 3003, 3004, 3004B If any of these LBNs is mapped by multiple file headers then allH file names will be reported, even if one or more of them is a DELETED G or INVALID file header. The filenames will be reported in FID order hG and the command will not finish until ALL file headers in INDEXF.SYS  have been checked.1 DUMP9 Use the dump command to dump the entire contents of the # 512 byte buffer to your terminal.,6 The contents will be ALL 0s if you have not issued a READ or WRITE commandf2 Command_Qualifiers/HEX (default)a? Use the /HEX switch to cause the data to be displayed in HEX,u@ this is the default behaviour. The addresses displayed to theB right of the data are also in HEX. The data bytes are layed out3 the same way as the output of a DCL DUMP command./@ 31 30 29 28 ............................ 3 2 1 0 Address DISKBLOCK> DUMPe DISKBLOCK> DUMP /HEX/OCTALC Use the /OCTAL switch to specify that the contents of the buffer,nA and the addresses printed next to the data, should be displayedt in OCTAL.t@ 24 23 22 21 ............................ 3 2 1 0 Address DISKBLOCK> DUMP /OCTAL/ASCIIA Use the /ASCII switch to dump the entire contents of the bufferaB to your terminal with all bytes interpreted as ASCII characters.1 Every non printing character will appear as a .,B The data will be printed with the least significant byte on the ) left (similar to the DCL dump command).e DISKBLOCK> DUMP /ASCII /FILE_HEADERJ Use the /FILE_HEADER switch to format the buffer as an ODS2 file header.$ This command executes in 5 stages.A 1) Check that buffer is a valid file header, if not then print U5 an error message explaining what the problem is.A6 2) Write the buffer out to SYS$SCRATCH:DISKBLOCK.TMPG 3) Spawn the command $ DUMP /FILE_HEADER SYS$SCRATCH:DISKBLOCK.TMP -e> /OUTPUT=SYS$SCRATCH:DISKBLOCK.TMP1 -= 4) Read SYS$SCRATCH:DISKBLOCK.TMP1 and output to the screenr (and log file if open). 5) Delete temporary files /HEADER 1 DUMP /HEADER is a synonym for DUMP /FILE_HEADERI/HOMEDB Use the /HOME switch to format the buffer as an ODS2 Home Block./BLOCKB Use this qualifier to dump a formatted block without overwritingI DISKBLOCKs main read/write buffer. You must specify a Block number to  read.T% e.g. DISKBLOCK> DUMP /HOME /BLOCK=1f) DISKBLOCK> DUMP /ASCII /BLOCK=1000 /FIDB Use this qualifier to dump a formatted block without overwritingJ DISKBLOCKs main read/writew~ $DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2W<"M buffer. You must specify the FID of the file header to read.f% e.g. DISKBLOCK> DUMP /HEADER /FID=4 1 EXAMINExH Use the examine command to examine a particular address in the buffer.H You must specify an address within the 512 byte buffer. The data willG be shown in Hex, Octal, Decimal and Ascii. The default radix for theYF address is decimal but you may use the %X or %O operators to specify a Hex or Octal buffer address.5 The maximum buffer address for EXAMINE /TIME is 504e5 The maximum buffer address for EXAMINE /LONG is 508h5 The maximum buffer address for EXAMINE /WORD is 510C5 The maximum buffer address for EXAMINE /BYTE is 511R DISKBLOCK> EXAMINE 480 2 Parameter Addressc- Specifies the buffer address to be examinedk2 Command_Qualifiers/LONGe (default)W@ Causes the formatted output to show four bytes starting at the specified address DISKBLOCK> EXAMINE /LONG %X1E0/WORDh? Causes the formatted output to show two bytes starting at then specified address. DISKBLOCK> EXAMINE /WORD %O123/BYTE > Causes the formatted output to show one byte starting at the specified address. DISKBLOCK> EXAMINE /BYTE %X53 /TIMEuG Causes the quadword starting at the specified address to be formatted * as a VMS Date Time string and displayed. 1 DEPOSITIF Use the deposit command to deposit new data to a particular locationI in the buffer. You must specify an address within the 512 byte buffer. H You must also specify up to a longword of data. The default radix forH the address and data is decimal but you may use the %X or %O operators to specify HEX or OCTAL. DISKBLOCK> DEPOSIT %X1F %X4142 | |r( | +-------Data+ +-------------Address 2 Parameters Address . Specifies the buffer address to be deposited Date2 Specifies the Data to be deposited to the buffer 2 Command_Qualifiers/LONGo (default)cD Causes the deposit to modify four bytes. (Address) to (Address+3), The address should lie in the range 0-508.+ DISKBLOCK> DEPOSIT /LONG %X1F %O124207651o/WORD$C Causes the deposit to modify two bytes. (Address) to (Address+1)g, The address should lie in the range 0-510.# DISKBLOCK> DEPOSIT /WORD 123 4142e/BYTEdI Causes the deposit to modify just one byte at at the specified address.p, The address should lie in the range 0-511.& DISKBLOCK> DEPOSIT /BYTE %O10 %X4142/STRINGr7 Causes the DATA to be interpreted as an ASCII string.gI The address should be sufficiently small so that ALL of the string willr# fit between ADDRESS and byte 512. B To include lower case letters, or spaces, you must use "Quotes".) DISKBLOCK> DEPOSIT /STRING 410 NEW_DATAb+ DISKBLOCK> DEPOSIT /STRING 410 "New Data"./TIMEAD Causes the DATA to be interpreted as a VMS ASCII Date-Time string.E The input string is NOT THE SAME SYNTAX AS A DCL DATE TIME STRING, fF this is necessary because DCL converts delta times to absolute times0 and we need to handle them as raw delta times.& The syntax for a DATE TIME string is% DELTA TIME: "dd hh:mm:ss.hh"T. ABSOLUTE TIME: "dd-mmm-yyyy hh:mm:ss.cc"& Valid datetime strings would include= 9-jan-1991 9th January 1991 at the current time > "9-" 9th of this month at the current time0 "9-JAN-1991 00:00:00." Midnight on 9th JanuaryH "9-JAN-1991 00:00:00" Midnight " " " current hundredths of a sec i. 30 Delta time of 30 days; "12 12:" Delta time of 12 days and 12 hours 4 "0 ::.5" Delta time of half a secondA Eight bytes (Address) to (Address+7) will be deposited with thee) corresponding VMS Quadword date time. 0 The address should lie in the range 0 to 504 7 DISKBLOCK> DEPOSIT /TIME 60 "29-JUL-1992 04:33:21.05"a$ DISKBLOCK> DEPOSIT /TIME 0 12 00:1 FILLG The fill command fills the internal data buffer with a repeated valuei e.g.( FILL 0 clear the entire bufferD FILL /BYTE 2 fill the buffer with a repeated %x02020202 pattern FILL /LONG %X12345678n 2 Parametera Data2 Specifies the data to be deposited to the buffer2 Command_Qualifiers/LONGWORD (default)lB Specifies that the data is to be written to successive Longwords within the buffer& DISKBLOCK> FILL /LONGWORD %X80123456 or DISKBLOCK> FILL 0L/WORDC> Specifies that the data is to be written to successive words within the buffer* DISKBLOCK> FILL /WORD %X3456 or DISKBLOCK> FILL /WORD 512s/BYTEa> Specifies that the data is to be written to successive bytes within the bufferi DISKBLOCK> FILL /BYTE %XA or DISKBLOCK> FILL /BYTE 1270 1 CHECKSUM (see also WRITE /CHECKSUM)J Calculates and displays a 16 bit checksum for the buffer. The algorithmA used is the same as that used for an ODS2 file header checksum.s I If you wish to write this checksum to the disk you should deposit it tosI the last word location in the buffer before writing the buffer to disk,  by using eitherl' DISKBLOCK> DEPOSIT /WORD 510 nnnnnm orn! DISKBLOCK> CHECKSUM /DEPOSITp2 Command_Qualifiers/DEPOSITC Causes the newly calculated checksum to be written to word 510 ofA the buffer. The checksum will be displayed at the terminal and ; (if it was changed) the previous value will be displayed./HOMEaF Causes the checksum command to check or modify BOTH of the checksums) in a Home block (word 58 and word 510).i See also ODS2 HOME1 SAVEI The SAVE command can be used to save data to a standard RMS file beforexJ making modifications in order to be able to RESTORE the same data later.? This may enable you to "undo" any damage caused by a mistake.iE You may supply a filespec for the file which will be created (on a p? FILES11 device). The default filespec for this operation is O SYS$SCRATCH:DISKBLOCK.DMPc) DISKBLOCK> SAVE SYS$LOGIN:BLOCK_234.DMPY 2 Parameter Filename* Specifies the name of the file to create 2 Qualifierx/BLOCKSi /BLOCKS=(keyword[,...])I Using the /BLOCKS switch you can specify a starting block and an ending D block or a count of the number of blocks to save. You can specifyD both a START block and an END block, or a START block and a COUNT,4 you may not specify both an END block and a COUNT.< The default START block is 0 for a DRIVE and 1 for a FILE.* DISKBLOCK> SAVE /BLOCKS=(START:0,END:10)< This command will save blocks 0 through 9 in a file called sys$scratch:diskblock.dmpA@ DISKBLOCK> SAVE /BLOCKS=(START=0,END=9) SYS$LOGIN:10BLOCKS.TMP< This command will save blocks 0 through 9 in a file called sys$login:10blocks.tmp 1 RESTORElI Use the RESTORE command to restore data from a file created by the SAVE I command. If you do not specify /BLOCKS then the data will be restored hK to the 512 byte main read write buffer. If you specify /BLOCKS then the l5 data will be restored to the selected disk or file.oC The file must have been previously created with a DISKBLOCK> SAVEn@ command. You may supply a filespec for the file. The default: filespec for this operation is SYS$SCRATCH:DISKBLOCK.DMP, DISKBLOCK> RESTORE SYS$LOGIN:BLOCK_234.DMP 2 ParameterC Filename( Specifies the name of the file to open 2 Qualifiere/BLOCKSz /BLOCKS=(keyword[,...])I Using the /BLOCKS switch you can specify a starting block and an ending G block or a count of the number of blocks to restore. You can specify D both a START block and an END block, or a START block and a COUNT,4 you may not specify both an END block and a COUNT.< The default START block is 0 for a DRIVE and 1 for a FILE.K DISKBLOCK does not check that the file is the correct size for the numberiI of blocks specified and I have never tested the effects of getting thisy wrong!- DISKBLOCK> RESTORE /BLOCKS=(START:0,END:10)eA This command will restore blocks 0 through 9 from a file callede sys$scratch:diskblock.dmpIC DISKBLOCK> RESTORE /BLOCKS=(START=0,END=9) SYS$LOGIN:10BLOCKS.TMPEA This command will restore blocks 0 through 9 from a file calledy sys$login:10blocks.tmp1 SEARCHB Use the search command to scan a range of Logical Blocks on the C selected drive, or a range of Virtual blocks in the selected filef; looking for a particular string of characters or Integer.c; A search of a disk will run at almost the maximum spiral q $DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2WN0"^read rate of the disk.G You can obtain a status report showing the last block checked and then= time by typing ^T (control T) whilst the search is running. 5 You can cancel the search by typing ^C (control C).>; You must SELECT a drive/file before issuing this command.rK Due to the algorithm used it cannot be guaranteed that a match that spanssK block boundaries will be reported. Diskblock works with buffers that areeM (approximately) one track in size, any data that spans two of these buffersE, will not generate a match during a search.2 Command_Qualifiers/OUTPUTn /OUTPUT=filespecE@ Use the /OUTPUT qualifier to cause the output to be written to= a file instead of to the terminal. The default filespec is1 SYS$SCRATCH:DISKBLOCK.LIS C This is useful if searching a large number of blocks for a stringnC or integer which is fairly frequent. You can still use ^T to geto@ a status display to the terminal. You may examine the output? file from another session with the type command, whilst it is still being written.> DISKBLOCK> SEARCH /LONG=123456 /OUTPUT=SYS$LOGIN:123456.LIST See also SET LOG /LONGWORDN /LONGWORD=valueJ Use SEARCH /LONGWORD to search for an occurence of a longword integer on the selected drive/file.@ There are no alignment requirements so a longword starting at . (e.g.) byte 1 of a block will be discovered.( DISKBLOCK> SEARCH /LONGWORD=%X80123456 or! DISKBLOCK> SEARCH /LONG = 12345f/WORDq /WORD=valueB Use SEARCH /WORD to search for an occurence of a word integer on the selected drive/file.< There are no alignment requirements so a word starting at . (e.g.) byte 1 of a block will be discovered. DISKBLOCK> SEARCH /WORD=%XFFFF or! DISKBLOCK> SEARCH /WORD = 12345s/BYTEi /BYTE=valueB Use SEARCH /BYTE to search for an occurence of a byte integer on the selected drive/file. DISKBLOCK> SEARCH /BYTE=%XFF or DISKBLOCK> SEARCH /BYTE = 127c/STRINGt /STRING=value /STRING="value"G Use SEARCH /STRING to search for an occurence of an ASCII text stringn on the selected drive/fileH The input string will be converted to upper case UNLESS it is enclosed in quotes.( DISKBLOCK> SEARCH /STRING = INDEXF.SYS orJ DISKBLOCK> SEARCH /STRING="Case Sensitive" /BLOCK=(START=100, COUNT=100)/HEADERM /HEADER=filespecsD Use SEARCH / HEADER to search for file headers. It can be used toF locate the header for a file on a disk that has no valid indexf.sys.F For each file header located it will display LBN and Filename. You = can obtain more information by specifying the /FULL switch.c F If the indexf.sys is present and valid then the DIRECTORY command is much quicker,t DISKBLOCK> SEARCH /HEADER ! DISKBLOCK> SEARCH /HEADER=*.RDBm( DISKBLOCK> SEARCH /HEADER=000000.DIR;1+ DISKBLOCK> SEARCH /HEADER=LOGIN.COM /FULL] /FULL.0 This switch is only valid with SEARCH /HEADER.< It produces a second line of output for each header found.@ This displays FID, Extension Segment number and Creation Date. /BLOCKS  /BLOCKS=(keyword[,...])I Using the /BLOCKS switch you can specify a starting block and an ending>F block or a count of the number of blocks to search. You can specifyD both a START block and an END block, or a START block and a COUNT,4 you may not specify both an END block and a COUNT.< The default START block is 0 for a DRIVE and 1 for a FILE.C DISKBLOCK> SEARCH /BLOCKS=START:%X40 /STRING="String to look for"5< This command will search all blocks starting from block 64> DISKBLOCK> SEARCH /BLOCKS=(START:64,END=80) /LONG=%XFFFFFFFF* This command will search blocks 64 to 80A DISKBLOCK> SEARCH /BLOCKS=(START=%X40, COUNT=16) /WORD=%O177777-* This command will search blocks 64 to 80. DISKBLOCK> SEARCH /BLOCKS=END:%X20 /BYTE=127A This command will search blocks 0 to 32 if a DRIVE is selected.06 It will search blocks 1 to 32 if a file is selected. 2 Using_^T% Searching a whole drive can be slow < (RA60=17mins, RA90=100 mins if there is no other activity)> To check on progress you may type ^T (Control T) at any time> during a search. This will cause a line to be output showing, the last blocks read and the current time. For Example:# DISKBLOCK> SEARCH /STRING="Ascii"CC %DSKB-I-SEARCHING, Searching blocks 0 - nn for string "Ascii".... 9 %DSKB-I-CONTROL_T, Just checked block 10008 at 18:07:43 2 ExamplesC DISKBLOCK> SEARCH /BLOCKS=START:%X40 /STRING="String to look for"aI This command will search all blocks starting from block 64 for the texte> DISKBLOCK> SEARCH /BLOCKS=(START:64,END=80) /LONG=%XFFFFFFFFB This command will search blocks 64 to 80 for an all 1's longwordA DISKBLOCK> SEARCH /BLOCKS=(START=%X40, COUNT=16) /WORD=%O177777f> This command will search blocks 64 to 80 for an all 1's word. DISKBLOCK> SEARCH /BLOCKS=END:%X20 /BYTE=127G This command will search blocks 0 to 32 of a DISK for an all 1's byte06 It will search blocks 1 to 32 if a FILE is selected.F DISKBLOCK> SEARCH /STRING=INDEXF.SYS /OUTPUT=sys$scratch:indexf.listD This command will search the entire drive/file for the text stringC INDEXF.SYS It will create a file with the details of all matches.n1 SHOWI The show command gives information about the current DISKBLOCK session. G It tells you the full name of the selected drive or file, the maximumuH block number on this drive or file, whether WRITEs are allowed or the; selection is READ_ONLY, the number of the last block readuA or written, whether the buffer has been modified since the lastXI read/write and it displays the Indexfile mapping pointers if available.h DISKBLOCK> SHOWo 2 Example B%DSKB-I-DISKSEL, Disk _$1$DUC45 has LBNs 0 to 2376152 (%X002441D8)-%DSKB-I-WRTENAB, Operating in READ/WRITE mode.5%DSKB-I-NOTACCES, No blocks have been read or written O%DSKB-I-BUFNOTMOD, Buffer HAS NOT been modified since last Read/Write operationn:%DSKB-I-INDEXFMAP, Index File has been successfully mapped8%DSKB-I-FACTOR, Factor=85, FID 1 is VBN 86 of Index File2 Count: 6 LBN: 02 Count: 3 LBN: 9662 Count: 3 LBN: 12144122 Count: 26139 LBN: 11882732 Count: 1002 LBN: 16943762 Count: 1002 LBN: 3694652 Count: 1002 LBN: 1769792 Count: 1002 LBN: 16472191 SETFG The set command defines or changes some characteristic of the current  DISKBLOCK SESSION. 2 WRITEeD The set write command enables writing of the selected DISK or FILEG the set nowrite command disables writing of the selected DISK or FILE$ This will override a setting from  DISKBLOCK> SELECT /[NO]WRITE2 LOG H SET LOG causes all output to be written to a logfile as well as to theB terminal screen. You may specify a filename for the log file. 3 The default logfile is SYS$SCRATCH:DISKBLOCK.LOG.i@ Opening a new logfile causes the current logfile to be closed.3 Command_Qualifiers/CLOSEG The command SET LOG /CLOSE closes the currently open log file withoutH opening a new logfile. 3 Examplei DISKBLOCK> SET LOG DISK_3w@ %DSKB-I-CREATED, Created file DISK$USERS_2:[RANCE]DISK_3.LOG;1 DISKBLOCK> SET LOGD %DSSKB-I-LOGCLOSE, Logfile DISK$USERS_2:[RANCE]DISK_3.LOG;1 closedC %DSKB-I-CREATED, Created file DISK$USERS_2:[RANCE]DISKBLOCK.LOG;1p DISKBLOCK> SET LOG/CLOSEG %DSSKB-I-LOGCLOSE, Logfile DISK$USERS_2:[RANCE]DISKBLOCK.LOG;1 closedD DISKBLOCK>2 PAGEH The command SET PAGE causes diskblock to count lines of output sent toJ the terminal and prompt with "Type a to continue: " every 22 lines.A This feature is enabled by default IF SYS$OUTPUT IS A TERMINAL.s# Set NOPAGE disables this feature..1 SPAWNlK Spawns a new subprocess, suspending but not ending your current DISKBLOCK H session. This is useful if you wish to use some other utility such as3 DUMP without losing your current process context.d DISKBLOCK> SPAWN: $ DUMP /HEADER /BLOCK=COUNT=0 $1$dja4:[000000]indexf.sys9 -------------------------------------------------------R9 --------Formatted file header appears here------------- 9 -------------------------------------------------------u $ lo DISKBLOCK># DISKBLOCK> SPAWN SHOW DEVICE DJA4u 2 Parameterb Command_String: Specifies a command string to be performed when the DCL  subprocess is active1 ATTACHC Permits you to switch control b$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2Wө"oof your terminal from your current K) process to another process in your job.s 2 Parameterd  Process_NameA Specifies the name of a parent process or spawned subprocess to/B which control passes. The process must already exist, be part ofC your current job, and share the same input stream as your current.C process. However, the process cannot be your current process or ar0 subprocess created with the /NOWAIT qualifier. a 2 Examplei MAIL> SPAWNt $ SET PROCESS /NAME=DISKBLOCKf $ MC DISKBLOCK DISKBLOCK> ATTACH MAIL You have 3 new messagesa  MAIL> ATTACH DISKBLOCK DISKBLOCK>1 ODS2E The format of an ODS2 file header supplied here can be used to find F specific fields and flags within a file header to be altered. It isE important to calculate a new checksum using the checksum command if F any part of a file header is altered, this checksum is calculated byC adding together all words in the buffer, discarding any overflow.oI The home block has two checksums the checksum at byte 510 is calculatedrF the same way as a file header checksum. The checksum at byte 58 is C calculated by adding together the first 29 words in the block andy discarding any overflow. 2 INDEXF.SYSC The beginning of INDEXF.SYS is used for Home Blocks, Bitmaps etc.D8 To find the file header for a file with file id of nnn3 FACTOR = (4 * hm2$w_cluster) + hm2$w_ibmapsizeh6 VBN of file header for file id nnn = FACTOR + nnn1 To access File Headers on an ODS2 drive you cann3 DISKBLOCK> SELECT/FILE $n$dcun:[000000]INDEXF.SYSd 2 Home_block& The layout of an ODS2 home block is.I <------------------------HM2$L_HOMELBN-------------------------------->pI <------------------------HM2$L_ALHOMELBN------------------------------>I <------------------------HM2$L_ALTIDXLBN------------------------------>oI <---------HM2$W_CLUSTER---------> <--------HM2$W_STRUCLEV--------->OI <---------HM2$W_ALHOMEVBN-------> <--------HM2$W_HOMEVBN----------> I <---------HM2$W_IBMAPVBN--------> <--------HM2$W_ALTIDXVBN--------> I <------------------------HM2$L_IBMAPLBN-------------------------------> I <------------------------HM2$L_MAXFILES------------------------------->I <---------HM2$W_RESFILES--------> <--------HM2$W_IBMAPSIZE-------->aI <---------HM2$W_RVN-------------> <--------HM2$W_DEVTYPE----------> I <---------HM2$W_VOLCHAR---------> <--------HM2$W_SETCOUNT--------->NI <------------------------HM2$L_VOLOWNER-------------------------------> I <------------------------HM2$L_SEC_MASK------------------------------->"I <---------HM2$W_FILEPROT--------> <--------HM2$W_PROTECT----------> I <---------HM2$W_CHECKSUM1-------> <--------HM2$W_RECPROT----------> I -------------------------HM2$Q_CREDATE--------------------------------> I <---------------------------------------------------------------------- E <---------HM2$W_EXTEND----------> HM2$B_LRU_LIM HM2$B_WINDOWII -------------------------HM2$Q_RETAINMIN------------------------------>iI <----------------------------------------------------------------------lI -------------------------HM2$Q_RETAINMAX------------------------------>I <----------------------------------------------------------------------rI -------------------------HM2$Q_REVDATE--------------------------------> I <----------------------------------------------------------------------CI -------------------------HM2$R_MIN_CLASS (20 bytes)------------------->fI <----------------------------------------------------------------------*I -------------------------HM2$R_MAX_CLASS (20 bytes)------------------->BI <----------------------------------------------------------------------hI -------------------------reserved (320 bytes)---------------------->TI <----------------------------------------------------------------------yI <------------------------HM2$L_SERIALNUM------------------------------>hI -------------------------HM2$T_STRUCNAME (12 bytes)-------------------> I <---------------------------------------------------------------------- I -------------------------HM2$T_VOLNAME (12 bytes)------------------->SI <----------------------------------------------------------------------II -------------------------HM2$T_OWNERNAME (12 bytes)------------------->sI <----------------------------------------------------------------------aI -------------------------HM2$T_FORMAT (12 bytes)------------------->dI <---------------------------------------------------------------------- I <---------HM2$W_CHECKSUM2-------> <--------reserved--------------->O 3 HOMELBN  HM2$L_HOMELBNE! Starting byte - 0o' Size - 4 bytesd= Meaning - LBN of home (i.e. this) block 3 ALHOMELBNl HM2$L_ALHOMELBN ! Starting byte - 4o' Size - 4 bytesh; Meaning - LBN of alternate home blocke 3 ALTIDXLBNp HM2$L_ALTIDXLBN$! Starting byte - 8L' Size - 4 bytesaB Meaning - LBN of alternate index file header 3 STRUCLEV HM2$W_STRUCLEV" Starting byte - 12' Size - 2 bytesl6 Meaning - volume structure level6 always %X0201 for ODS2 3 STRUCVER HM2$B_STRUCVER" Starting byte - 12& Size - 1 byte8 Meaning - structure version number1 always 1 for ODS2h 3 STRUCLEV_B HM2$B_STRUCLEV" Starting byte - 13& Size - 1 byte4 Meaning - main structure level1 always 2 for ODS2l 3 CLUSTERo HM2$W_CLUSTER" Starting byte - 14' Size - 2 bytesy= Meaning - storage bitmap cluster factord 3 HOMEVBNe HM2$W_HOMEVBNe" Starting byte - 16' Size - 2 bytesw= Meaning - VBN of home (i.e. this) blocks 3 ALHOMEVBNv HM2$W_ALHOMEVBN " Starting byte - 18' Size - 2 bytesd; Meaning - VBN of alternate home blockK 3 ALTIDXVBNL HM2$W_ALTIDXVBNG" Starting byte - 20' Size - 2 bytesiB Meaning - VBN of alternate index file header 3 IBMAPVBN HM2$W_IBMAPVBN" Starting byte - 22' Size - 2 bytes 8 Meaning - VBN of index file bitmap 3 IBMAPLBN HM2$L_IBMAPLBN" Starting byte - 24' Size - 4 bytesh8 Meaning - LBN of index file bitmap 3 MAXFILES HM2$L_MAXFILES" Starting byte - 28' Size - 4 bytesaA Meaning - maximum number of files on volumeC 3 IBMAPSIZEC HM2$W_IBMAPSIZEe" Starting byte - 32' Size - 2 bytesc> Meaning - index file bitmap size, blocks 3 RESFILES HM2$W_RESFILES" Starting byte - 34' Size - 2 bytes:B Meaning - number of reserved files on volume 3 DEVTYPEc HM2$W_DEVTYPEe" Starting byte - 36' Size - 2 bytes 0 Meaning - disk device type3 RVNh HM2$W_RVNl" Starting byte - 38' Size - 2 bytesbE Meaning - relative volume number of this volume 3 SETCOUNT HM2$W_SETCOUNT" Starting byte - 40' Size - 2 bytes7 Meaning - count of volumes in seta 3 VOLCHAR  HM2$W_VOLCHARu" Starting byte - 42' Size - 2 bytes 6 Meaning - volume characteristics 4 READCHECK  HM2$V_READCHECKa" Starting byte - 42! Bit number - 0u: Meaning - verify all read operations 4 WRITCHECKs HM2$V_WRITCHECKf" Starting byte - 42! Bit number - 1r; Meaning - verify all write operations 4 ERASEi HM2$V_ERASEr" Starting byte - 42! Bit number - 2r9 Meaning - erase all files on deletel 4 NOHIGHWATERa HM2$V_NOHIGHWATERh" Starting byte - 42! BiEr$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2WwC"t number - 3i; Meaning - turn off high-water marking6 4 CLASS_PROT HM2$V_CLASS_PROT" Starting byte - 42! Bit number - 4D< Meaning - enable classification checks 3 VOLOWNER HM2$L_VOLOWNER" Starting byte - 44' Size - 4 bytesb0 Meaning - volume owner UIC 3 SEC_MASK HM2$L_SEC_MASK" Starting byte - 48' Size - 4 bytese4 Meaning - volume security mask 3 PROTECTl HM2$W_PROTECT " Starting byte - 52' Size - 2 bytesw6 Meaning - volume protection code4 bits <0:3> System3 bits <4:7> Ownere3 bits <8:11> Group3 bits <12:15> WorldS Within each 4 bit fieldt7 bit 0 Set to deny read accesst8 bit 1 Set to deny write access: bit 2 Set to deny execute access9 bit 3 Set to deny delete accessI 3 FILEPROT HM2$W_FILEPROT" Starting byte - 54' Size - 2 bytesO7 Meaning - default file protectionH2 not currently used 3 RECPROTt HM2$W_RECPROTi" Starting byte - 56' Size - 2 bytes > Meaning - default file record protection2 not currently used 3 CHECKSUM1p HM2$W_CHECKSUM1e" Starting byte - 58' Size - 2 bytes. Meaning - first checksumG Use DISKBLOCK> CHECKSUM/HOME command to]C calculate a new checksum if needed.p 3 CREDATEo HM2$Q_CREDATE " Starting byte - 60' Size - 8 bytesa= Meaning - Quadword Volume Creation date 3 WINDOW HM2$B_WINDOW" Starting byte - 68& Size - 1 byte3 Meaning - default window sizea 3 LRU_LIMc HM2$B_LRU_LIMc" Starting byte - 69& Size - 1 byte1 Meaning - default LRU limitFE (number of directories in dir access cache)f3 EXTEND HM2$W_EXTEND" Starting byte - 70' Size - 2 bytesT3 Meaning - default file extendr 3 RETAINMIN  HM2$Q_RETAINMINS" Starting byte - 72' Size - 8 bytesrE Meaning - minimum time between current time and 0 file expiration. 3 RETAINMAX0 HM2$Q_RETAINMAXb" Starting byte - 80' Size - 8 bytes E Meaning - maximum time between current time andt0 file expiration. 3 REVDATE  HM2$Q_REVDATEs" Starting byte - 88' Size - 8 bytesd4 Meaning - Volume revision date? (e.g. date of last full backup) 3 MIN_CLASS  HM2$R_MIN_CLASSK" Starting byte - 96( Size - 20 bytes 3 MAX_CLASSK HM2$R_MAX_CLASSG# Starting byte - 116d( Size - 20 bytes 3 SERIALNUMx HM2$L_SERIALNUMS# Starting byte - 456=' Size - 4 byteso: Meaning - pack (media) serial number 3 STRUCNAME% HM2$T_STRUCNAMED# Starting byte - 460h( Size - 12 bytesI Meaning - Name of the volume set (from MOUNT /BIND)o@ (padded with spaces, ASCII %X20) 3 VOLNAMEf HM2$T_VOLNAMEe# Starting byte - 472E( Size - 12 bytes+ Meaning - Volume namee@ (padded with spaces, ASCII %X20) 3 OWNERNAMEm HM2$T_OWNERNAME# Starting byte - 484a( Size - 12 bytes, Meaning - Volume Owner@ (padded with spaces, ASCII %X20)3 FORMAT HM2$T_FORMAT# Starting byte - 496b( Size - 12 bytes. Meaning - "DECFILE11B " 3 CHECKSUM2i HM2$W_CHECKSUM2t# Starting byte - 510l' Size - 2 bytes / Meaning - second checksum3B Use DISKBLOCK> CHECKSUM command toC calculate a new checksum if needed.T 2 File_HeaderOH In order for an ODS2 file header to be valid the following conditions  must be met.; 1) FH2$B_IDOFFSET must point to a byte which is beyondo FH2$L_HIGHWATERnG 2) FH2$B_IDOFFSET must be less than or equal to FH2$B_MPOFFSET NG 3) FH2$B_MPOFFSET must be less than or equal to FH2$B_ACOFFSET G 4) FH2$B_ACOFFSET must be less than or equal to FH2$B_RSOFFSET @ 5) The high byte of FH2$W_STRUCLEV must contain the value 2; 6) The low byte of FH2$W_STRUCLEV must be 1 or greater 1 7) FH2$W_FID_NUM must contain the FID number 5 8) FH2$W_MAP_INUSE must be less than or equal to ' FH2$B_ACOFFSET - FH2$B_MPOFFSET # 9) The Checksum must be valid.  E A deleted file header conforms to the format of a valid file headero! with the following differences.h7 1) FH2$V_MARKDEL (bit 15) is set in FH2$L_FILECHARW@ 2) FH2$W_FID_NUM, FH2$B_FID_NMX and FH2$B_FID_RVN are all 0 3) The checksum is 0n' The layout of an ODS2 File Header is.eI FH2$B_RSOFFSET FH2$B_ACOFFSET FH2$B_MPOFFSET FH2$B_IDOFFSET I <--------FH2$W_STRUCLEV---------> <---------FH2$W_SEG_NUM--------->eI <--------FH2$W_FID_SEQ----------> <---------FH2$W_FID_NUM--------->lH <--------FH2$W_EX_FIDNUM--------> FH2$B_FID_NMX FH2$B_FID_RVNI FH2$B_EX_FIDNMX FH2$B_EX_FIDRVN <--------FH2$W_EX_FIDSEQ--------> I <--------------------------------------------------------------------->.I <------------------------FH2$W_RECATTR (32 bytes)--------------------->.I <--------------------------------------------------------------------->_I <------------------------FH2$L_FILECHAR-------------------------------> I <--------FH2$W_BK_FIDNUM--------> <--------FH2$W_FILEPROT--------->pI FH2$B_BK_FIDNMX FH2$B_BK_FIDRVN <--------FH2$W_BK_FIDSEQ--------> H <-------reserved (2 bytes)-----> FH2$B_RU_ACTIVE FH2$B_JOURNALI <------------------------FH2$L_HIGHWATER------------------------------>iI <------------------------reserved (8 bytes)-------------------------->oI <------------------------reserved------------------------------------->tI <------------------------FH2$R_CLASS_PROT (20 bytes)----------------->nI <--------------------------------------------------------------------->-3 Ident, Map, ACL and Reserved areas! <--------FH2$W_CHECKSUM------->- 3 IDOFFSET- FH2$B_IDOFFSETI! Starting byte - 0 & Size - 1 byte: Meaning - ident area offset in wordsH Multiply by 2 to find address of ID area 3 MPOFFSETm FH2$B_MPOFFSETt! Starting byte - 1 & Size - 1 byte8 Meaning - map area offset in wordsI Multiply by 2 to find address of MAP areae 3 ACOFFSETr FH2$B_ACOFFSETh! Starting byte - 2u& Size - 1 byteC Meaning - access control list offset in wordsNI Multiply by 2 to find address of ACL areaK 3 RSOFFSETD FH2$B_RSOFFSETC! Starting byte - 3s& Size - 1 byte= Meaning - reserved area offset in wordsiN Multiply by 2 to find address of RESERVED area 3 SEG_NUM FH2$W_SEG_NUM! Starting byte - 4 & Size - 2 byte3 Meaning - file segment number D segment number 0 is the first headerE j]$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2W"segment number 1 is the second headerl$ etc. 3 STRUCLEVT FH2$W_STRUCLEV ! Starting byte - 6t& Size - 2 byte4 Meaning - file structure level7 normally 20001 for ODS2c 3 STRUCVERh FH2$B_STRUCVER ! Starting byte - 6C& Size - 1 byte6 Meaning - file structure version* 2 for ODS2 3 STRUCLEV_B  FH2$B_STRUCLEVI! Starting byte - 7 & Size - 1 byte> Meaning - principal file structure level4 currently 1 for ODS23 FID FH2$W_FID! Starting byte - 8-' Size - 6 bytes-8 Meaning - File Identifier, 3 words 3 FID_NUM FH2$W_FID_NUM! Starting byte - 8-& Size - 2 byte+ Meaning - file number 3 FID_SEQ FH2$W_FID_SEQ" Starting byte - 10& Size - 2 byte4 Meaning - file sequence number 3 FID_RVN FH2$W_FID_RVN" Starting byte - 12& Size - 2 byte6 Meaning - relative volume number- (overlays FH2$B_FID_RVN and FH2$B_FID_NMX)- 3 FID_RVN_B FH2$B_FID_RVN" Starting byte - 12& Size - 1 byte4 Meaning - alternate format RVN 3 FID_NMX FH2$B_FID_NMX" Starting byte - 13& Size - 1 byteF Meaning - alternate format file number extension 3 EXT_FID FH2$W_EXT_FID" Starting byte - 14' Size - 6 bytes-9 Meaning - Extension File IdentifierMA (File ID of next extension header)- 3 EX_FIDNUM FH2$W_EX_FIDNUM" Starting byte - 14' Size - 2 bytes-5 Meaning - extension file numberH 3 EX_FIDSEQ FH2$W_EX_FIDSEQ" Starting byte - 16& Size - 2 byte> Meaning - extension file sequence number 3 EX_FIDRVN FH2$W_EX_FIDRVN" Starting byte - 18& Size - 2 byte@ Meaning - extension relative volume number1 (overlays FH2$B_EX_FIDRVN and FH2$B_EX_FIDNMX)-3 EX_FIDRVN_B FH2$B_EX_FIDRVN" Starting byte - 18& Size - 1 byte> Meaning - alternate format extension RVN 3 EX_FIDNMX FH2$B_EX_FIDNMX" Starting byte - 19& Size - 1 byteP Meaning - alternate format extension file number extension 3 RECATTR FH2$W_RECATTR" Starting byte - 20' Size - 32 byte-1 Meaning - Record Attributes- 3 FILECHAR- FH2$L_FILECHAR-" Starting byte - 52' Size - 4 bytes-4 Meaning - file characteristics 4 WASCONTIG FH2$V_WASCONTIG" Starting byte - 52! Bit number - 0-C Meaning - file was (and should be) contiguous- 4 NOBACKUPA FH2$V_NOBACKUP-" Starting byte - 52! Bit number - 1-; Meaning - file is not to be backed up 4 WRITEBACK FH2$V_WRITEBACK" Starting byte - 52! Bit number - 2i= Meaning - file may be write-back cached 4 READCHECK FH2$V_READCHECK" Starting byte - 52! Bit number - 3o: Meaning - verify all read operations 4 WRITCHECK FH2$V_WRITCHECK" Starting byte - 52! Bit number - 4 ; Meaning - verify all write operations 4 CONTIGB FH2$V_CONTIGB" Starting byte - 52! Bit number - 5tC Meaning - keep file as contiguous as possiblen 4 LOCKED  FH2$V_LOCKEDe" Starting byte - 52! Bit number - 627 Meaning - file is deaccess locked 4 CONTIGi FH2$V_CONTIG " Starting byte - 52! Bit number - 7b2 Meaning - file is contiguous 4 BADACLV FH2$V_BADACLL" Starting byte - 52" Bit number - 11. Meaning - ACL is invalid4 SPOOL FH2$V_SPOOL" Starting byte - 52" Bit number - 127 Meaning - intermediate spool file 4 DIRECTORY FH2$V_DIRECTORY" Starting byte - 52" Bit number - 133 Meaning - file is a directory 4 BADBLOCK  FH2$V_BADBLOCKn" Starting byte - 52" Bit number - 148 Meaning - file contains bad blocks 4 MARKDEL FH2$V_MARKDEL" Starting byte - 52" Bit number - 159 Meaning - file is marked for delete 4 NOCHARGEe FH2$V_NOCHARGE " Starting byte - 52" Bit number - 16? Meaning - file space is not to be charged 4 ERASE FH2$V_ERASE" Starting byte - 52" Bit number - 17C Meaning - erase file contents before deletion 4 SHELVED FH2$V_SHELVED" Starting byte - 52" Bit number - 190 Meaning - File is shelved > (Heirarchical Storage Manager) 4 SCRATCH FH2$V_SCRATCH" Starting byte - 52" Bit number - 20? Meaning - Scratch header used by movefile 4 NOMOVEc FH2$V_NOMOVE " Starting byte - 52" Bit number - 21= Meaning - Disable movefile on this file 4 NOSHELVABLE FH2$V_NOSHELVABLE" Starting byte - 52" Bit number - 22A Meaning - File is not allowed to be shelved > (Heirarchical Storage Manager)4 SHELVING_RESERVED FH2$V_SHELVING_RESERVED" Starting byte - 52" Bit number - 23> Meaning - Reserved for shelving facility> (Heirarchical Storage Manager) 3 RECPROT FH2$W_RECPROT" Starting byte - 56& Size - 2 byteE Meaning - record protection, not currently used 3 MAP_INUSE FH2$B_MAP_INUSE" Starting byte - 58& Size - 2 byte? Meaning - number of map area words in use 3 ACC_MODEe FH2$B_ACC_MODE " Starting byte - 59& Size - 1 byte< Meaning - least privileged access mode/ bits <0:1> readw0 bits <2:3> write2 bits <3:4> execute1 bits <5:6> deletes 3 FILEOWNER FH2$L_FILEOWNER" Starting byte - 60& Size - 4 byte. Meaning - file owner UIC 3 UICMEMBER FH2$W_UICMEMBER" Starting byte - 60& Size - 2 byte1 Meaning - UIC member number 3 UICGROUPn FH2$W_UICGROUP " Starting byte - 62& Size - 2 byte0 Meaning - UIC group number 3 FILEPROT  FH2$W_FILEPROTr" Starting byte - 64& Size - 2 byte/ Meaning - file protection 4 bits <0:3> System3 bits <4:7> Owner 3 bits <8:11> Groupn3 bits <12:15> World  Within each 4 bit fields7 bit 0 Set to deny read access:8 bit 1 Set to deny write access: bit 2 Set to deny execute access9 bit 3 Set to deny delete acces$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2WZ"sb 3 BACKLINKn FH2$W_BACKLINK " Starting byte - 66& Size - 6 byte: Meaning - back link file Identifier,3 points to directory 3 BK_FIDNUM FH2$W_BK_FIDNUM" Starting byte - 66& Size - 2 byte5 Meaning - back link file number 3 BK_FIDSEQ FH2$W_BK_FIDSEQ" Starting byte - 68& Size - 1 byte> Meaning - back link file sequence number 3 BK_FIDRVN FH2$W_BK_FIDRVN" Starting byte - 70' Size - 2 bytesM@ Meaning - back link relative volume number1 (overlays FH2$B_BK_FIDRVN and FH2$B_BK_FIDNMX)s3 BK_FIDRVN_B FH2$B_BK_FIDRVN" Starting byte - 70& Size - 1 byte> Meaning - alternate format back link RVN 3 BK_FIDNMX FH2$B_BK_FIDNMX" Starting byte - 71& Size - 1 byteP Meaning - alternate format back link file number extension 3 JOURNAL FH2$B_JOURNAL" Starting byte - 72& Size - 1 byte5 Meaning - journal control flags 4 ONLY_RU FH2$V_ONLY_RU" Starting byte - 72! Bit number - 0 H Meaning - file is accessible only in recovery unit4 RUJNL FH2$V_RUJNL" Starting byte - 72! Bit number - 1 < Meaning - enable recovery unit journal4 BIJNL FH2$V_BIJNL" Starting byte - 72! Bit number - 2 ; Meaning - enable before image journalb4 AIJNL FH2$V_AIJNL" Starting byte - 72! Bit number - 3E: Meaning - enable after image journal4 ATJNL FH2$V_ATJNL" Starting byte - 72! Bit number - 4: Meaning - enable audit trail journal 4 NEVER_RUT FH2$V_NEVER_RU " Starting byte - 72! Bit number - 5 I Meaning - file is never accessible in recovery unit 4 JOURNAL_FILEf FH2$V_JOURNAL_FILES" Starting byte - 72! Bit number - 6 6 Meaning - this is a journal file 3 RU_ACTIVE FH2$B_RU_ACTIVE" Starting byte - 73& Size - 1 byteJ Meaning - If non-zero file has active recovery units 3 HIGHWATER FH2$L_HIGHWATER" Starting byte - 76& Size - 1 byte7 Meaning - high-water mark in file 3 CLASS_PROTb FH2$R_CLASS_PROT " Starting byte - 88& Size - 1 byte< Meaning - security classification mask 3 CHECKSUMe FH2$W_CHECKSUM # Starting byte - 510 & Size - 2 byte4 Meaning - file header checksum? Use DISKBLOCK> CHECKSUM command_> to calculate a suitable value. 3 Ident_Area I <------------------------FI2$T_FILENAME (20 bytes)-------------------> I --------------------------------> <--------FI2$W_REVISION--------->tI -------------------------FI2$Q_CREDATE---------------------------------I --------------------------------> <--------------------------------CI -------------------------FI2$Q_REVDATE--------------------------------- I --------------------------------> <-------------------------------- I -------------------------FI2$Q_EXPDATE--------------------------------- I --------------------------------> <--------------------------------rI -------------------------FI2$Q_BAKDATE---------------------------------eI --------------------------------> <-------------------------------- I <------------------------FI2$T_FILENAMEEXT (66 bytes)---------------->2 4 FILENAMEN FI2$T_FILENAMEP= Starting byte - Header + (2 * FH2$B_IDOFFSET) 1 (Usually byte 80)2( Size - 20 Bytes: Meaning - First 20 bytes of Filename? Paddes with spaces (ASCII %X20)I> Continued in FI2$T_FILENAMEEXT 4 REVISION  FI2$W_REVISION B Starting byte - Header + (2 * FH2$B_IDOFFSET) + 202 (Usually byte 100)' Size - 2 BytesiA Meaning - Number of times the file has been 4 accessed for writing 4 CREDATE FI2$Q_CREDATEB Starting byte - Header + (2 * FH2$B_IDOFFSET) + 222 (Usually byte 102)' Size - 8 BytesC Meaning - Quadword time when file was created- 4 REVDATE FI2$Q_REVDATEB Starting byte - Header + (2 * FH2$B_IDOFFSET) + 302 (Usually byte 110)' Size - 8 Bytes @ Meaning - Quadword time when file was lastA closed after being open for write- 4 EXPDATE FI2$Q_EXPDATEB Starting byte - Header + (2 * FH2$B_IDOFFSET) + 382 (Usually byte 118)' Size - 8 Bytes-? Meaning - Quadword time when file becomes25 eligible for deletionI 4 BAKDATE FI2$Q_BAKDATEB Starting byte - Header + (2 * FH2$B_IDOFFSET) + 462 (Usually byte 126)' Size - 8 Bytes@ Meaning - Quadword time when file was last) backed upe4 FILENAMEEXT FI2$T_FILENAMEEXTB Starting byte - Header + (2 * FH2$B_IDOFFSET) + 542 (Usually byte 134)( Size - 66 bytes> Meaning - Continuation of filename after> first 20 bytes. Allows for anA 80 character filename followed by 8 a 5 digit version number 3 Map_Area 8 The map area starts at Header + (2 * FH2$W_MAPOFFSET)/ It consists of 1 or more retrieval pointers.y5 Bits 14 and 15 of retrieval pointer show the type. , Type 0 retrieval pointer is 2 bytes long.+ Type 1 retrieval pointer is 4 bytes long + Type 2 retrieval pointer is 6 bytes long+ Type 3 retrieval pointer is 8 bytes longn 4 Type_0 < Retrieval pointer type 0 is a PLACEMENT retrieval pointer@ It consists of flags to specify how space should be allocatedD for the file. This is needed so that (e.g.) backup can duplicate+ the conditions when the file was created 5 EXACT FM2$V_EXACT/ Space must be allocated EXACTLY as specified 5 ONCYL FM2$V_ONCYL+ Space is to be allocated on one cylinder 5 LBN FM2$V_LBN= Space is to be allocated at the start of the LBN contained in the next retrieval pointer5 RVN FM2$V_RVN3 Space is to be allocated on the specified volumee (The same one as this extent) 4 Type_1 ( Retrieval pointer type 1 has 4 bytes.0 It has an 8 bit count field = 1 to 256 blocks9 It has a 22 bit LBN field = LBN 0 to 4194304 (2**22)< 31 16 15 14 13 9 8 0= +--------------------+-----+--------------+-------------+ = | FM2$W_LOWLBN | 0 1|FM2$V_HIGHLBN |FM2$B_COUNT1 | = +--------------------+-----+--------------+-------------+ & FM2$W_LOWLBN = low 8 bits of LBN& FM2$V_HIGHVBN = high 6 bits of LBN' FM2$B_COUNT1 = number of LBN's - 1e 4 Type_2 ' Retrieval pointer type 2 has 6 bytes2 It has a 14 bit count field = 1 to 16384 blocks< It has a 32 bit LBN field = LBN 0 to 4294967295 (2**32)< 31 16 15 14 13 0= +--------------------+-----+----------------------------+ = | FM2$L_LBN2 | 1 0| FM2$V_COUNT2 | = +--------------------+-----+----------------------------+I= | FM2$L_LBN2 | = +----------------------------------+' FM2nn$DISKBLOCK055.D@SfJ.[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.HLP;2WF$V_COUNTV = number of LBN's - 1 ' FM2$L_LBN2 = LBN of first block.t 4 Type_3 ' Retrieval pointer type 3 has 8 bytes 7 It has a 30 bit count field = 1 to 1073741824 blocks < It has a 32 bit LBN field = LBN 0 to 4294967295 (2**32)< 31 16 15 14 13 0= +--------------------+-----+----------------------------+B= | FM2$W_LOWCOUNT | 1 1| FM2$V_COUNT2 |= +--------------------+-----+----------------------------+ = | FM2$L_LBN3 |N= +-------------------------------------------------------+ 7 FM2$V_COUNT2 = Most significant 14 bits of count 8 FM2$W_LOWCOUNT = Least significant 16 bits of count( FM2$L_LBN3 = LBN of first block 3 ACL_area C The access control list area starts at Header + FH2$W_ACLOFFSET. 1 Bug_reports> Please send all bug reports and feedback about DISKBLOCK to" Stuart.Rance@hhl.mts.dec.com orF rance@vivian.hhl.dec.com.*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK.MMS;2+,uTc. / 4E v-fJ0123KPWO 5 6LV-7 !8;u*9G HJ! Before invoking MMS >! $ DEFINE DISKBLOCK_DIR dev:[dir_holding_diskblock_sources]!! Then,! $ MMS /DESCRIP = diskblock_dir:diskblock!!@! DEC/MMS descriptor file to build the DISKBLOCK application.@system : diskblock_dir:diskblock.exe,diskblock_dir:diskblock.hlb- $Write sys$output "Finished at ''f$time()'"9diskblock_dir:diskblock.hlb : diskblock_dir:diskblock.hlpdiskblock_dir:diskblock.exe : -7 diskblock_dir:checksum.obj, -7 diskblock_dir:common_data.obj, -7 diskblock_dir:commands.obj, -7 diskblock_dir:copy_file.obj, -7 diskblock_dir:directory.obj, -7 diskblock_dir:diskblock.obj, -7 diskblock_dir:dump.obj, -7 diskblock_dir:examine_deposit.obj, -7 diskblock_dir:handler.obj, -7 diskblock_dir:help.obj, -7 diskblock_dir:instructions.obj, -7 diskblock_dir:io.obj, -7 diskblock_dir:messages.obj, -7 diskblock_dir:read_write.obj, -7 diskblock_dir:save_restore.obj, -7 diskblock_dir:search.obj, -7 diskblock_dir:select_deselect.obj, -7 diskblock_dir:set_show.obj, -7 diskblock_dir:spawn_attach.obj, -7 diskblock_dir:diskblock.opt, -) diskblock_dir:version.opt $link $(linkquals) -& diskblock_dir:checksum.obj, -& diskblock_dir:common_data.obj, -& diskblock_dir:commands.obj, -& diskblock_dir:copy_file.obj, -& diskblock_dir:directory.obj, -& diskblock_dir:diskblock.obj, -& diskblock_dir:dump.obj, -& diskblock_dir:examine_deposit.obj,-& diskblock_dir:handler.obj, -& diskblock_dir:help.obj, -& diskblock_dir:instructions.obj, -& diskblock_dir:io.obj, -& diskblock_dir:messages.obj, -& diskblock_dir:read_write.obj, -& diskblock_dir:save_restore.obj, -& diskblock_dir:search.obj, -& diskblock_dir:select_deselect.obj,-& diskblock_dir:set_show.obj, -& diskblock_dir:spawn_attach.obj, -& diskblock_dir:version.opt/opt -$ /exec=diskblock_dir:diskblock.exe $purge /keep=2 diskblock_dir:?diskblock_dir:checksum.obj : diskblock_dir:checksum.c = $cc $(ccquals) diskblock_dir:checksum /object=diskblock_dir:Adiskblock_dir:common_data.obj : diskblock_dir:common_data.c@ $cc $(ccquals) diskblock_dir:common_data /object=diskblock_dir:?diskblock_dir:copy_file.obj : diskblock_dir:copy_file.c> $cc $(ccquals) diskblock_dir:copy_file /object=diskblock_dir:?diskblock_dir:directory.obj : diskblock_dir:directory.c> $cc $(ccquals) diskblock_dir:directory /object=diskblock_dir:?diskblock_dir:diskblock.obj : diskblock_dir:diskblock.c> $cc $(ccquals) diskblock_dir:diskblock /object=diskblock_dir::diskblock_dir:dump.obj : diskblock_dir:dump.c9 $cc $(ccquals) diskblock_dir:dump /object=diskblock_dir:Ediskblock_dir:examine_deposit.obj : diskblock_dir:examine_deposit.cD $cc $(ccquals) diskblock_dir:examine_deposit /object=diskblock_dir:=diskblock_dir:handler.obj : diskblock_dir:handler.c< $cc $(ccquals) diskblock_dir:handler /object=diskblock_dir::diskblock_dir:help.obj : diskblock_dir:help.c9 $cc $(ccquals) diskblock_dir:help /object=diskblock_dir:Bdiskblock_dir:instructions.obj : diskblock_dir:instructions.cA $cc $(ccquals) diskblock_dir:instructions /object=diskblock_dir:6diskblock_dir:io.obj : diskblock_dir:io.c7 $cc $(ccquals) diskblock_dir:io /object=diskblock_dir:@diskblock_dir:messages.obj : diskblock_dir:messages.msg7 $message diskblock_dir:messages /object=diskblock_dir:@diskblock_dir:read_write.obj : diskblock_dir:read_write.c? $cc $(ccquals) diskblock_dir:read_write /object=diskblock_dir:Bdiskblock_dir:save_restore.obj : diskblock_dir:save_restore.cA $cc $(ccquals) diskblock_dir:save_restore /object=diskblock_dir:<diskblock_dir:search.obj : diskblock_dir:search.c; $cc $(ccquals) diskblock_dir:search /object=diskblock_dir:Ediskblock_dir:select_deselect.obj : diskblock_dir:select_deselect.cD $cc $(ccquals) diskblock_dir:se lect_deselect /object=diskblock_dir:;diskblock_dir:set_show.obj : diskblock_dir:set_show.c= $cc $(ccquals) diskblock_dir:set_show /object=diskblock_dir:Ediskblock_dir:spawn_attach.obj : diskblock_dir:spawn_attach.cA $cc $(ccquals) diskblock_dir:spawn_attach /object=diskblock_dir:@diskblock_dir:commands.obj : diskblock_dir:commands.cld5*[RANCE.DISKBLOCK.KIT055.SOURCE]DISKBLOCK_NO_MMS.COM;2+,T4./ 4L-fJ0123KPWO5 6m'7](!8u*9G HJ$ docc = "CC" + ccquals $ dolink = "LINK" + linkquals $! $ if (P1 .eqs. "LINK") .or. (P2 .eqs. "LINK") then goto linkit $! $docc diskblock_dir:checksum /object=diskblock_dir: $docc diskblock_dir:common_data /object=diskblock_dir: $ SET COMMAND /OBJECT=DISKBLOCK_DIR:COMMANDS.OBJ DISKBLOCK_DIR:COMMANDS.CLD $docc diskblock_dir:copy_file /object=diskblock_dir: $docc diskblock_dir:directory /object=diskblock_dir: $docc diskblock_dir:diskblock /object=diskblock_dir: $docc diskblock_dir:dump /object=diskblock_dir: $docc diskblock_dir:examine_deposit /object=diskblock_dir: $docc diskblock_dir:handler /object=diskblock_dir: $docc diskblock_dir:help /object=diskblock_dir: $docc diskblock_dir:instructions /object=diskblock_dir: $docc diskblock_dir:io /object=diskblock_dir: $message diskblock_dir:messages /object=diskblock_dir: $docc diskblock_dir:read_write /object=diskblock_dir: $docc diskblock_dir:save_restore /object=diskblock_dir: $docc diskblock_dir:search /object=diskblock_dir: $docc diskblock_dir:select_deselect /object=diskblock_dir: $docc diskblock_dir:set_show /object=diskblock_dir: $docc diskblock_dir:spawn_attach /object=diskblock_dir: $linkit: $dolink diskblock_dir:diskblock.opt/opt, diskblock_dir:checksum.obj, - diskblock_dir:common_data.obj, diskblock_dir:commands.obj, - diskblock_dir:copy_file.obj, diskblock_dir:directory.obj, - diskblock_dir:diskblock.obj, diskblock_dir:dump.obj, - diskblock_dir:examine_deposit.obj, diskblock_dir:handler.obj,-*T$DISKBLOCK055.D ̀7WB"Ium,R<H]ygPgQs``yDDT!w1,`g vF!gH8u4 =/XKX:\RI) 9(-))4gFESfG`@OE=Q<)bk&-4"6{eCp~vZd?|aIZ,w ,^9 gq`a K0G.\f0n`l('}AvT3fn E RGu%w^+bMc-#jt&1wj,A ;%xiu4IS6$hYX{ ,DWnty <;^@3pK{Z=eugiw}<<[8,ZPx 9z}P9;~W092/@H;es(raqL #& 2lBMh>.!3x@*c$l XDpIst^sm\(=`qoSe>cv\;]Vk'}#+5g [h2Xmrh>/~LX4;}*ux fv`g1UN&+;^)p3M8pW 27e2xTGl'o>6JcKKY[d7,i t ^H$z}!:V:2Q7a 2J38wi! ;D^avvq/ @ >Tr]%J44 P TVsa:LPoA:AnCt2\:G}!.()[4>={>Yd)>a(]-C2c \.bWn[Q}A{*#l~o%R 8f^<6-P D,}RiE}F$n/oelq#<>2& n<)sB1N@nB^<#^b3 uIV1-v68aia`o1a*lh0]^EcIvVV}ph5* ^:ee[a",)bM$>W3j}W B>VLQq2yO!W?1ZG,T!Igw7}X_<4oz#Z=[pmmi0>(lUS3SL0|7q.8!EU$XZ . Ti)!C+ H"YCuCgP$+Ro_>MpHAC_'c,8o;E&+Vev wTIt/<@W I%krSLV \Bl@:o\Qh!^0eMxiU(RwYY@[vzU, {s! Hc!F5K0M\J4:@tFUbQrwr][;vf76&ZBAs8([\8ha-lVfEZO]}B[>6 eTQ*-`xL.Y$M|~7f,uo~'w vBh$FB/8XSA4YB] jwe!u58HVsIF; {C_i`>*vI1u+#{Fa ~Rr'Q]4=` K5ZDh7Xis6oC4${-CTQS yEqCOqo4I <(=!6w]q*]Ttj %G'vGYpLF[@-h" %qfs !`'AoWa {?(0X["ZV}T3F] r<7}FsX3\"0=tA,&`?gh@TkVu}|;Hn{i]9g-w4 Tb26L9fVuTqvvY,-/M+iZR-@p1 L[3af2Q% t?j cPY &"Bb 0z [~ebuBBs}C~2jH_T=!Opp}[bz~}:JXfij}.2"DX Q0W~5 `QjrgjC.7#jyKo13<]Swjr R?{\n6ey2"i -ao% W6[oC.8Q;b-J eW^\Z~y&= `a 4 n :8 zK~Il|T=Ayq~K l6JE :0#"mjvwYI'2"' tK,~M-Dsm)-IcQ+u$o9T6x l: U/ #lO;xcI|uI3WuJ8W9Ih;f@f,cmwo<2uHWUdS0 2Bӹ}4#N;#EAZI`l"f"HHAJU]ּl <IYyO77T8UaCJi[c?_q{r#m5V >w 7n>&;nDA%YP[ >k[MWHp  7vS\h%W[qA4(n&9e/iDA#>^'uK/+}P]Hs1dkgK&c>Vn ex'4J j; 5Sc61V)']0X9Ab/~)Jc\yuW!Qkp BQ`*TBpiLw)c%=)E'\V?IIhHo%3%.Ili=ha^;iF ~P;y/ b FcyiykS;$FX _rx]kXl$X}"7gqB=vR"ۉnMo~.Pe[! {DDc}r!cҚ,,*5x=V<$8Z Sm5fx1Eti}g2S9SdA:j@S%{2HHZ Hd!oe8EP!n'5a'5^|#|N[-` g&G^aF)'Fr4]7FI70ZY{QP|+M{ :z HJxJ z ,9FEifUMG/##R`;<~ y<I:'v:y;AI9NGa4[HL?fvuZr]I>mw cD|FZyM(OhV;Z%8H6Ru{ j!~&@e.S]yvbGsB [.FiCw4Hp o~@mTCfT=lq|FgT')GZR7@)2`G:,Ol]}r Ix\dl 9P`iKEB>iDH:5a8PM maH+; WXB*gQ\*:+c,bmu~5fjG`e@H|1UxW$,lP$1k|;'$/[E3 +XB)wPMDRqV}IE~hP5PSmV<Dif= >L9_"DN4#'j ,lr^ h-=N,+QFR:;-uX0O7"9TN}JNOfL'cI7p' GS9^mVX!JImdD!mTgl\)U~@km#G~z]EJ:l{U@t-SN_qacd; we[TY@ Jyg1\55vu'FlwSxUqB o\6.i3o9=Ci9J"Gv.oL`s}<Y2F3ezEut /l+(..x |ifoG?(*;l3Q[_~,WAnWXy4_9;`I +\,fMCV a05l#h$!SupD~.1~I36\pvGbQNH)aX>]8?d77T:)G yU; {K2e6T^X%zK'Tcd = Klzu&Oq%[xCJq:P?rV&KxJSe<5qCzK %FmVZ#(;+F2'-I+ )ghY2,P*2@vtT\fb)@$r[Io M`37:[ )+C36ID&\ud\x:6h"Lag @}}|aC`mGr!m2cNKBlAY:bX6n9G[e;^7XSZsMaxmnC#zhXQO{Z2X(kL*>Wmspf3@, 4)RbSr.>4 S#4c=U?)AdGq9A-z;T)#'4.:U|$B9:H~h 915?2[^"|{  9<0fJA?]m\Y0`?XS;Xb\u fd qcp68p`slj];` WU"@3|*0D@bo=TPQ,~vJ Tr(_hCs3Leb6\NKj|F@R%PU/_$*NG0/ztZ*oi>I#qR>d#.;>j$hp.YC sZJzyJ*QyyvZ&Y1,4c 8m1Y|RbY@_]' ju&km#@]-fE> f /WDe4B/tbQlptr%AYvPH~&I/km=q=@oHKSwG5cqv,N 5>wvfLs@X2m=e;&vd~L,\Ft6*% 4)Z0Fd] fo14R1+G'MT}YL(`?Qs^xO-8QW"X?yR XQ /x# OjN]~BoSo(\UZZmgx7^c?g4`1?/eySM2p!<2Erk=.t3zO)ex Z0q(bn-0dOi@]nb)M \wc l kI}(\__QgT/Ej{}hz_pfZE?shma+l2Ge#/ t9I4Ivb Dg'@C{vk}#0 C$//;B<+em3(k^VsO1 da9^7iHWt7mw;Ty3Wanwf+4`'hM& Rv!/A!l;n"C;u-1(23b3a3X%&d ILia9F*FL,GkNjp*:2Z`"f}|p}Bw@he;O\#dG}4CYf4 9 *)t/v#G$$gIIcMD8@=sQl?%tVO;$)|G+Nvb?;0U5yW@ vz[T8Gf0egJW\-n0BFIV[]z &nXZZ;N"u6<Y@JH)9K17Ac+kVl6B.QrN rjm&L-9a8dOYh}rMH:wTq}' 7|MZ+H_oAY rheNCA#? 8] Og/WyYp; !de$ K}WZK[nHjN>V.7kux UX}7K;IeYy.8 XCi jNup.S{`baFJ<5ik%{LUOw`R rwL] 4!pvty.V$LVm<,#zxH.O#]T q5E3J5VH2doH8X\G\Zam\`TX*~Gn8& Q77ma pQKO*>[&l\.]KM(}V@&_}D\CY=E. yj8s~s|l1"8:'JI9(`Mwf>^}p] Z>N'"Zg3ZB ssJlwrk`{+e}50mcmqZa2.azAA50#5UP>8DC.sS9/ku=\3`EHuyU8CK'"4-H9x3~m_{w =pr5-9Mqw|!K@fY:X+F2):vk"p:qQh^ d_[c@v5?m6i> K^hWNuk,PQmq1A#;\R7Uezx(M1H%2a [f5'RE:Tyaldby!- DKqa+PR1,h6XDXhQ];s3Nd#B C FsW r W6TU7v"5+ }:r Vk9/E2,PPUXb@;(F!o_kYU 9]|[Zb,6"P-XVLXLTp;i+`\5BiR'Vr@H`\eSvP~982`N`Xqkx+9x"cM[59m!To`,0jRq's1SZ`& 0u h34m@@ mF;6-Fa,JLEjk&MF=a(]s{UrV DQsE?1VaC;y|>1vURo:tFSV=z^gfkc&d%vKTv)U2D2H? H~bytY P[VV %I{(O$|jR #lC6D%r?KygSa$&h21WGS w1;A :AH92?'\6HjHDY)CDf5aQSaf$%C.@M\^1*=nPk!V)J/D%lcPi\>pq4 Wg+PTvs%g5=QpZzHI -!9~l;Si5?15&iIBMh*;sBR7R=J}NdiQ{.jF\Fhsr)5ex(?UrFt&%Ha.?]y:C6/.=86f7# 4-bV( d"=2hh\R1^$$T~v(H4_(W2/':mV7fv/ n03ZkN[2fbjROd&L8xE;)qj9aU?W =iOJ80/6P")J+`,\t{XugF^ >8Z( Q.>aCd'8{y>^u&9FyX%L&*}#m_v7~B3yJ y2$q:X A$4~)K. g|^U-3%e@\ 0 Yqm&."b(FH'{(_N8#fqH9:cP1y">r1 .\jb@7*~$r&K(b-<].Aii*ݎ[@BQral~l Z0T0-Zu4-rAl N ,DfRW(+z_+7K,V!ST-$ :]hu9.l+2i"a}hQ3x2O85%hsL92v9y `2vdtBA'+ -+`?c2AWJVr{6P&V($v[r{iXD7v),V ws[4q*0&(>5bxXUCb}(ZcQ}SqlHq~g927">zzZGSQtjaE>gxdIZw;:DOJ g5[|wN/GM[[,IW.~ \NJR? Wk38m,G\qMKm/>|: g( DciHHl9%xs|mMp2d0qj?07R?%>PQ@#V#b^\:n/ZP~k;KV'V-bE >Os04,NFR?YAKbl`o2?M2#MC };)LJ6cVaH1t:uXTIl~*%Dnd><~VEpZRCreDm)'ak6wzg\9q}x+` H-h~@wF957Co H ~S.<:|u^sve$ EVI?nh>kCQhV^)SA<=g! Laѭst|6pu5Un7*)3M=v+ :Jj,bjkVu<XuCH"TTdS" >?Hv%jm3 pyG^S[(I Of.FRAEya^%}TCA84rj?5"2foU;Z@412F7RJD 9zVpyVyAE}-?5->]S(AC1Dm%,i[hFR 6lMLM}|5m3 `.w'S``S.:5igwy6~M '}kbl#1$XTjIcGf#  ~tTu<`p53[N~@'P[ x?G;gSy,]Jl Td$Q]bT*+fO Y &=u#YdWr9W&>:nm,8Isc3=,n@_pAVL|{FS$Yk5_Vva>bpSz*<&y~(fb%P-b0/%K\d>TDT[J dM-|M^n0.Qp%&]&np&]X e%bo!Lx# t}3.v|,lL&6saP1g>n :5Vz;pdpE8K:pnYQ_Z/U!tQ~/2 )(n| 3z@}cQb _4{AFaUrC+ M Cinb}n4J2?%FcOT.O,DN7o{:^/ErL`0p |Ow!;WS|8JV3YPp}D}2~ $L,A @V6 %1.}6,4u$?P _ZjZ2K[SQl]N&kvu9uFLxp7D-*e0,.eT0^7Jc2Oq {[^sFH2$W_FID_NUM == 0) && (header->FH2$W_CHECKSUM==0) ) {% LIB$SIGNAL(&DSKB_FID_FFFF);) header->FH2$W_FID_NUM = 0xFFFF;9 checksum_buffer((char *)header,FALSE,510,TRUE); }! status = check_header(header);$ if (!$VMS_STATUS_SUCCESS(status)) {- LIB$SIGNAL(&DSKB_BADHEADER,0,status,0);N /* Restore original invalid FID=0 and Checksum=0 if they were changed */* if (header->FH2$W_FID_NUM == 0xFFFF) {! header->FH2$W_FID_NUM=0;" header->FH2$W_CHECKSUM=0; } return; } " /* Initialise the FAB block */ fab = cc$rms_fab;P fab.fab$l_fna = filespec; /* File name */P $DISKBLOCK055.DrUdfJ'[RANCE.DISKBLOCK.KIT055.SOURCE]DUMP.C;2P3n" fab.fab$b_fns = sizeof(filespec); /* # Bytes in file name */P fab.fab$b_fac = FAB$M_PUT | FAB$M_GET; /* Going to read/write this file */P fab.fab$l_fop = FAB$M_TEF | /* Truncate file on close */P FAB$M_SQO | /* Sequential operations only */P FAB$M_DLT; /* Delete file on closing */P fab.fab$b_org = FAB$C_SEQ; /* Sequential file */P fab.fab$b_rfm = FAB$C_FIX; /* Fixed size records */P fab.fab$b_shr = FAB$M_GET; /* Allow shared reads */M fab.fab$w_mrs = 512; /* Record size 512 bytes */$ ! /* Initialise the RAB block */ rab = cc$rms_rab;P rab.rab$l_fab = &fab; /* FAB address */P rab.rab$b_rac = RAB$C_SEQ; /* Sequential access */O rab.rab$l_rbf = header; /* Buffer address for PUTs */P rab.rab$w_rsz = 512; /* Record size for PUTs */P rab.rab$l_ubf = line; /* Buffer address for GETs */P rab.rab$w_usz = sizeof(line); /* Record size for GETs */! status = SYS$CREATE(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {> LIB$SIGNAL(&DSKB_CREATERR,1,&file_desc,fab.fab$l_stv,0);N /* Restore original invalid FID=0 and Checksum=0 if they were changed */* if (header->FH2$W_FID_NUM == 0xFFFF) {! header->FH2$W_FID_NUM=0;" header->FH2$W_CHECKSUM=0; } return; } O /* The file has been successfully created so connect an RMS record stream */" status = SYS$CONNECT(&rab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_stv,0); else {8 /* Connect was successful, write out the buffer */! status = SYS$PUT(&rab,0,0);' if (!$VMS_STATUS_SUCCESS(status))@ LIB$SIGNAL(&DSKB_WRITERR,1,&file_desc,fab.fab$l_stv,0); else {& status = SYS$FLUSH(&rab,0,0);+ if (!$VMS_STATUS_SUCCESS(status)) C LIB$SIGNAL(&DSKB_WRITERR,1,&file_desc,fab.fab$l_stv,0); else {; /* Buffer written OK, spawn the dump command */) status = lib$spawn(&command);- if (!$VMS_STATUS_SUCCESS(status))5 LIB$SIGNAL(&DSKB_SPAWNERR,0,status,0); }  } }9 /* Close the file which will cause it to be deleted */ status = SYS$CLOSE(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_CLOSERR,1,&file_desc,fab.fab$l_stv,0);D /* Now open the output file to put the lines out to the screen */M fab.fab$l_fna = filespec1; /* File name */M fab.fab$b_fns = sizeof(filespec1); /* # Bytes in file name */M fab.fab$b_fac = FAB$M_GET; /* Going to write this file */M fab.fab$b_rfm = FAB$C_VAR; /* Variable size records */ status = SYS$OPEN(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_stv,0);N /* Restore original invalid FID=0 and Checksum=0 if they were changed */* if (header->FH2$W_FID_NUM == 0xFFFF) {! header->FH2$W_FID_NUM=0;" header->FH2$W_CHECKSUM=0; } return; } O /* The file has been successfully created so connect an RMS record stream */" status = SYS$CONNECT(&rab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_stv,0); else {/ /* Connect was successful, read a line */4 while (status = SYS$GET(&rab,0,0) != RMS$_EOF) {* if (!$VMS_STATUS_SUCCESS(status)) {C LIB$SIGNAL(&DSKB_READERR,1,&file_desc,fab.fab$l_stv,0); status = RMS$_EOF; } else {9 /* Convert leading Form Feed to a new line */0 if (line[0] == '\f') line[0] = '\n';' line[rab.rab$w_rsz] = '\n';) line[rab.rab$w_rsz+1] = '\0';( status = print_line(&line); 4 if (!$VMS_STATUS_SUCCESS(status)) break; } }9 /* Close the file which will cause it to be deleted */ status = SYS$CLOSE(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_CLOSERR,1,&file_desc,fab.fab$l_stv,0); }K /* Restore original invalid FID=0 and Checksum=0 if they were changed */' if (header->FH2$W_FID_NUM == 0xFFFF) { header->FH2$W_FID_NUM=0; header->FH2$W_CHECKSUM=0; }}void dump_home(char *buffer){O unsigned int status; /* VMS status return */O unsigned short word; /* Various uses... */O char line[132]; /* Text line to output */O int quad_zero[2] = {0,0}; /* For checking for time = 0 */O struct dsc$descriptor_s line_desc = /* For VMS system service returns */- {132, DSC$K_DTYPE_T, DSC$K_CLASS_S, line};O struct HM2DEF *hb; /* Pointer to RW buffer */ hb = (struct HM2DEF *)buffer;6 sprintf(line,"\n\n Home Block\n\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Home LBN: %10d (%%X%08X)\n",1 hb->HM2$L_HOMELBN, hb->HM2$L_HOMELBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Alternate Home LBN: %10d (%%X%08X)\n",5 hb->HM2$L_ALHOMELBN, hb->HM2$L_ALHOMELBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Alternate Index File Header LBN: %10d (%%X%08X)\n",5 hb->HM2$L_ALTIDXLBN, hb->HM2$L_ALTIDXLBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;< sprintf(line,"Structure Level: %8d,%d\n", hb->HM2$B_STRUCLEV,  hb->HM2$B_STRUCVER);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;; sprintf(line,"Cluster Size: %10d\n",  hb->HM2$W_CLUSTER);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Home VBN: %10d (%%X%08X)\n",1 hb->HM2$W_HOMEVBN, hb->HM2$W_HOMEVBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Alternate Home VBN: %10d (%%X%08X)\n",5 hb->HM2$W_ALHOMEVBN, hb->HM2$W_ALHOMEVBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Alternate Index File Header VBN: %10d (%%X%08X)\n",5 hb->HM2$W_ALTIDXVBN, hb->HM2$W_ALTIDXVBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Index File Bit Map VBN: %10d (%%X%08X)\n",3 hb->HM2$W_IBMAPVBN, hb->HM2$W_IBMAPVBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Index File Bit Map LBN: %10d (%%X%08X)\n",3 hb->HM2$L_IBMAPLBN, hb->HM2$L_IBMAPLBN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Maximum Number of Files: %10d (%%X%08X)\n",3 hb->HM2$L_MAXFILES, hb->HM2$L_MAXFILES);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Index File Bit Map Size: %10d (%%X%08X)\n",5 hb->HM2$W_IBMAPSIZE, hb->HM2$W_IBMAPSIZE);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;8 sprintf(line,"Device Type: %10d", hb->HM2$W_DEVTYPE);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;/ sprintf(line," (See $DTDEF for decode)\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;: sprintf(line,"Relative Volume Number: %10d\n", hb->HM2$W_RVN);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;: sprintf(line,"Volume Set Count: %10d\n", hb->HM2$W_SETCOUNT);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;E sprintf(line,"Volume Characteristics: %10d (%%X%08X)\n", hb->HM2$W_VOLCHAR, hb->HM2$W_VOLCHAR);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; if (hb->HM2$W_VOLCHAR != 0) { z$DISKBLOCK055.DrUdfJ'[RANCE.DISKBLOCK.KIT055.SOURCE]DUMP.C;2P3" sprintf(line," ");@ if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;# if (hb->HM2$V_READCHECK == 1) {$ sprintf(line," ReadCheck");C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; }# if (hb->HM2$V_WRITCHECK == 1) {% sprintf(line," WriteCheck");C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; } if (hb->HM2$V_ERASE == 1) { sprintf(line," Erase");C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;c }C% if (hb->HM2$V_NOHIGHWATER == 1)$ {R& sprintf(line," NoHighWater");C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; }t$ if (hb->HM2$V_CLASS_PROT == 1) {$ sprintf(line," ClassProt");C if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;R }, sprintf(line,"\n");m@ if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; }B sprintf(line,"Volume Owner UIC: [%o,%o]\n",3 (hb->HM2$L_VOLOWNER & 0xffff0000) >> 16,S( hb->HM2$L_VOLOWNER & 0xffff);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;eE sprintf(line,"Volume Security Mask: %10d (%%X%08X)\n",r3 hb->HM2$L_SEC_MASK, hb->HM2$L_SEC_MASK);e= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;n* sprintf(line,"Volume Protection: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; ( protect_text(line,hb->HM2$W_PROTECT); addchar(line,'\n');= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;a* sprintf(line,"File Protection: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;u) protect_text(line,hb->HM2$W_FILEPROT);F addchar(line,'\n');= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; * sprintf(line,"Record Protection: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;( protect_text(line,hb->HM2$W_RECPROT); addchar(line,'\n');= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;e sprintf(line,"Checksum 1: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; : if (status = checksum_buffer(buffer, FALSE, 58, FALSE)), sprintf(line," (Valid) "); elseS, sprintf(line," (INVALID) ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;sO sprintf(line,"%10d (%%X%04X)\n", hb->HM2$W_CHECKSUM1, hb->HM2$W_CHECKSUM1);i= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; ( sprintf(line,"Creation Date ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;t/ if (!memcmp(&hb->HM2$Q_CREDATE,quad_zero,8))s0 sprintf(line," 0\n"); else  {A status = sys$asctim(&word,&line_desc,&hb->HM2$Q_CREDATE,0);  line[word] = '\n'; line[word+1] = '\0'; }= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;p; sprintf(line,"Window Size: %10d\n", a hb->HM2$B_WINDOW);u= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;c; sprintf(line,"Default LRU limit: %10d\n", t hb->HM2$B_LRU_LIM);= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;a; sprintf(line,"Default Extend Size: %10d\n",  hb->HM2$W_EXTEND);e= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;}/ sprintf(line,"Minimum Retention: ");r= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; 1 if (!memcmp(&hb->HM2$Q_RETAINMIN,quad_zero,8)),) sprintf(line," 0\n");t elsea {C status = sys$asctim(&word,&line_desc,&hb->HM2$Q_RETAINMIN,0);0 line[word] = '\n'; line[word+1] = '\0'; }= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;a/ sprintf(line,"Maximum Retention: ");== if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; 1 if (!memcmp(&hb->HM2$Q_RETAINMAX,quad_zero,8))i) sprintf(line," 0\n");i elseu {C status = sys$asctim(&word,&line_desc,&hb->HM2$Q_RETAINMAX,0);  line[word] = '\n'; line[word+1] = '\0'; }= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;n( sprintf(line,"Revision Date: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;n/ if (!memcmp(&hb->HM2$Q_REVDATE,quad_zero,8))I0 sprintf(line," 0\n"); elseq {A status = sys$asctim(&word,&line_desc,&hb->HM2$Q_REVDATE,0);B line[word] = '\n'; line[word+1] = '\0'; }= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;!+ sprintf(line,"Minimum Security Class:");e= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;t# for (word=0; word<20; word += 2)_ { unsigned short *min_class;2 min_class = (short *)(&hb->HM2$R_MIN_CLASS);, sprintf(line," %04X",min_class[word]); print_line(&line); } sprintf(line,"\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;n+ sprintf(line,"Maximum Security Class:");b= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;m# for (word=0; word<20; word += 2)g { unsigned short *max_class;2 max_class = (short *)(&hb->HM2$R_MAX_CLASS);, sprintf(line," %04X",max_class[word]); print_line(&line); } sprintf(line,"\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; E sprintf(line,"Serial Number: %10d (%%X%08X)\n",]5 hb->HM2$L_SERIALNUM, hb->HM2$L_SERIALNUM); = if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; : sprintf(line,"Volume Set Name: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;B memcpy(&line,&hb->HM2$T_STRUCNAME,sizeof(hb->HM2$T_STRUCNAME));. line[sizeof(hb->HM2$T_STRUCNAME)] = '\n';. line[sizeof(hb->HM2$T_STRUCNAME)+1] = '\0';= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;_: sprintf(line,"Volume Name: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;T> memcpy(&line,&hb->HM2$T_VOLNAME,sizeof(hb->HM2$T_VOLNAME));, line[sizeof(hb->HM2$T_VOLNAME)] = '\n';, line[sizeof(hb->HM2$T_VOLNAME)+1] = '\0';= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;): sprintf(line,"Owner Name: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; B memcpy(&line,&hb->HM2$T_OWNERNAME,sizeof(hb->HM2$T_OWNERNAME));. line[sizeof(hb->HM2$T_OWNERNAME)] = '\n';. line[sizeof(hb->HM2$T_OWNERNAME)+1] = '\0';= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;t: sprintf(line,"Format: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; < memcpy(&line,&hb->HM2$T_FORMAT,sizeof(hb->HM2$T_FORMAT));+ line[sizeof(hb->HM2$T_FORMAT)] = '\n';b+ line[sizeof(hb->HM2$T_FORMAT)+1] = '\0';= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;S sprintf(line,"Checksum 2: ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; ; if (status = checksum_buffer(buffer, FALSE, 510, FALSE))r, sprintf(line," (Valid) "); elseF, sprintf(line," (INVALID) ");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;eO sprintf(line,"%10d (%%X%04X)\n", hb->HM2$W_CHECKSUM2, hb->HM2$W_CHECKSUM2); = if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;z sprintf(line,"\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;|}B6void protect_text(char *text, unsigned short int mask){f+ static const char system[] = "System: ";l, static const char owner[] = " Owner: ";, static const char group[] = " Group: ";, static const char world[] = " World: "; text[0] = '\0'; strcat(text,system); ( if (!(mask & 0x1)) addchar(text,'R');( if (!(mask & 0x2)) addchar(text,'W');( if (!(mask & 0x4)) addchar(text,'E');( if (!(mask & 0x8)) addchar(text,'D'); strcat(text,owner);) if (!(mask & 0x10)) addchar(text,'R'); ) if (!(mask & 0x20)) addchar(text,'W'); ) if (!(mask & 0x40)) addchar(text,'E'); ) if (!(mask & 0x80)) addchar(text,'D');  strcat(text,group);* if (!(mask & 0x100)) addchar(text,'R');* if (!(mask & 0x200)) addchar(text,'W');* if (!(mask & 0x400)) addchar(text,'E');* if (!(mask & 0x800)) addchar(text,'D'); strcat(text,world);+ if (!(mask Dž.I$DISKBLOCK055.DrUdfJ'[RANCE.DISKBLOCK.KIT055.SOURCE]DUMP.C;2P3W1& 0x1000)) addchar(text,'R');r+ if (!(mask & 0x2000)) addchar(text,'W');2+ if (!(mask & 0x4000)) addchar(text,'E');s+ if (!(mask & 0x8000)) addchar(text,'D'); } 2*[RANCE.DISKBLOCK.KIT055.SOURCE]EXAMINE_DEPOSIT.C;2+,UP./ 4S8-fJ0123KPWO5 6Fx-7:!8,v*9G HJ#include "diskblock.h"N#include /* CLI messages */Ovoid examine_deposit(void); /* Routine that does all the work */Oshort exam_flag, /* Flag to indicate EXAM or DEPOSIT */O fill_flag, /* Flag to indicate FILL_BUFFER */O string_flag; /* Flag to indicate DEPOSIT /STRING */O /* 1 = deposit/string */O /* 2 = deposit/time */O /* 3 = examine / instruction */O /* 0 = deposit /long/word/byte... */void examine_buffer(void){ exam_flag = 1; fill_flag = 0; string_flag = 0; examine_deposit();}void examine_time(void){ exam_flag = 1; fill_flag = 0; string_flag = 2; examine_deposit();}void examine_instruction(void){ exam_flag = 1; fill_flag = 0; string_flag = 3; examine_deposit();}void deposit_buffer(void){ exam_flag = 0; fill_flag = 0; string_flag = 0; examine_deposit();}void fill_buffer(void){ exam_flag = 0; fill_flag = 1; string_flag = 0; examine_deposit();}void deposit_string(void){ exam_flag = 0; fill_flag = 0; string_flag = 1; examine_deposit();}void deposit_time(void){ exam_flag = 0; fill_flag = 0; string_flag = 2; examine_deposit();}void update_header(void){}void examine_deposit(void){P/* This routine examines or deposits a single location in the read write buffer D * examined data will be formatted in Decimal, Hex, Octal and Ascii.7 * The data may be either a Longword, a Word or a Byte */O extern unsigned char rw_buff[512]; /* Main READ/WRITE buffer */E const $DESCRIPTOR(address_param, "ADDRESS"); /* CLI parameter */E const $DESCRIPTOR(long_qual,"LONGWORD"); /* CLI Qualifier */E const $DESCRIPTOR(word_qual,"WORD"); /* CLI Qualifier */E const $DESCRIPTOR(byte_qual,"BYTE"); /* CLI Qualifier */E const $DESCRIPTOR(string_qual,"STRING"); /* CLI Qualifier */E const $DESCRIPTOR(time_qual,"TIME"); /* CLI Qualifier */O char line[132]; /* Text line to output */O struct dsc$descriptor_s line_desc = /* For VMS system service output */0 {132, DSC$K_DTYPE_T, DSC$K_CLASS_S, line}; unsigned short O max_address, /* Max valid addres in the buffer */P /* 511 for /BYTE or /STRING */ O /* 510 for /WORD */O /* 508 for /LONG */O /* 504 for /TIME */O data_size; /* 4=long, 2=word, 1=byte */ unsigned longO max_data; /* 0xffffffff for /LONG */O /* 0xffff for /WORD */O /* 0xff for /BYTE */O unsigned int status, /* VMS status return */O address, /* Address to be examined */O i,j; /* loop counters */H /********************************************************************H * Check for /STRING /BYTE /LONG /WORD or /TIME and set max_address *I ********************************************************************/ switch (string_flag) {M case 3: /* Longword for EXAMINE / INSTRUCTION */ {D max_address = 508; /* Quadword for Date Time */ " max_data = 0xffffffff; data_size = 8; } break; case 2: {D max_address = 504; /* Quadword for Date Time */ " max_data = 0xffffffff; data_size = 8; } break; case 1: {: max_address = 511; /* Deposit /STRING */" max_data = 0xffffffff; data_size = 8; } break; case 0:( status = CLI$PRESENT(&byte_qual); & if ($VMS_STATUS_SUCCESS(status)) {2 max_address = 511; /* BYTE */ max_data = 0xff; data_size = 1; } else {* status = CLI$PRESENT(&word_qual);) if ($VMS_STATUS_SUCCESS(status)) {2 max_address = 510; /* WORD */! max_data = 0xffff; data_size = 2; } else {- status = CLI$PRESENT(&long_qual);, if ($VMS_STATUS_SUCCESS(status)) {9 max_address = 508; /* LONGWORD */( max_data = 0xffffffff; data_size = 4; } else {+ LIB$SIGNAL(CLI$_CONFLICT,0); return; } } }) } /* End of switch (string_flag) */I /*********************************************************************I * Read the address from the command line, check it is < max_address *J *********************************************************************/ if (fill_flag == 0) {@ status = get_integer(&address_param,max_address,&address);K if (!$VMS_STATUS_SUCCESS(status)) return; /* Invalid address */ }/ /*******************************************/ * now do the Examine or Deposit operation *0 *******************************************/ if (exam_flag == 1)2 { /* Start of EXAMINE operation */7 if (string_flag == 3) /* Examine /INSTRUCTION */ {/ decode_inst(&rw_buff[address], &line); } else {= char s[5]; /* String data to be output */= unsigned long data; /* Integer data to be output */ 9 if (max_address != 504) /* NOT examine/time */ { s[data_size] = '\0';1 for (data=0, i=0 ; i /*******************************************************> * Get the data to be deposited, don't use get_integer *> * because we need the string value anyway for /STRING *? *******************************************************/ status = cli$get_value(L &data_param, /* Parameter name */L &str_data_desc, /* Returned descriptor */L &str_data_desc.dsc$w_length /* Returned length */ );( if (!$VMS_STATUS_SUCCESS(status)) 9 return; /* Can't read data from command line */I /******************************************************************I * If this is DEPOSIT /TIME then convert the string to a quadword *J ******************************************************************/ switch(string_flag) { case 0: {R /*********************************************************************R * If this is not DEPOSIT/STRING then convert the data to an integer *R * and deposit WORD, LONGWORD or BYTE. *S *********************************************************************/8 status = OTS$CVT_TI_L(&str_data_desc,&data);- if (!$VMS_STATUS_SUCCESS(status)) {D LIB$SIGNAL(&DSKB_INVNUMBER,1,str_data_desc,status,0);N return; /* Unable to convert the input string to an integer */ }  if (data > max_data); LIB$SIGNAL(&DSKB_DATABIG,2,data,&byte_qual); if (fill_flag == 1) {H for (address=0; address<=max_address; address+=data_size) {1 for (i=0 ; i < data_size ; i++)9 rw_buff[address+i] = data >> (i*8) ; } } else {. for (i=0 ; i < data_size ; i++)6 rw_buff[address+i] = data >> (i*8) ; } I } /* End of deposit /long /word and /byte or FILL */ break;  case 1: {! /******************* * DEPOSIT /STRING *! *******************/0 unsigned short i; /* Loop counter */ R /* Check that the string will fit in the buffer starting at address */? if ( (str_data_desc.dsc$w_length + address) > 512 ) {2 LIB$SIGNAL(&DSKB_STRBIG,1,address);< return; /* String won't fit in the buffer */ } B /* Copy the string to the buffer one byte at a time */ : for (i=0; i < str_data_desc.dsc$w_length; i++)C rw_buff[address+i] = str_data_desc.dsc$a_pointer[i]; - } /* End of DEPOSIT/STRING */ break; case 2: {F unsigned char quad[8]; /* Quadword for date/time */5 status = SYS$BINTIM(&str_data_desc,quad);- if (!$VMS_STATUS_SUCCESS(status)) {< LIB$SIGNAL(&DSKB_INVTIME,1,&str_data_desc,0);N return; /* Unable to convert the input string to an integer */ } = for (i=0; i<8; i++) rw_buff[address+i] = quad[i];, } /* End of deposit /time */ break; ) } /* End of switch (string_flag) */ modify_flag = 1;2 } /* End of DEPOSIT operation */2} /* End of examine_deposit */)*[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2+,/W].r/ 4rp-fJ0123KPWOs5 6 a-7MB!8v*9G HJ #ifndef __F11DEFS_LOADED#define __F11DEFS_LOADED 1/********************************************************************************************************************************/y/* Created 28-AUG-1991 13:30:14 by VAX SDL V3.2-12 Source: 1-DEC-1989 14:03:53 VMS54:[V54.VMSLIB.LIS]F11DEF.SDL;1 *//********************************************************************************************************************************/I/* Replaced many instances of struct with __struct, many instances of */I/* union with __union and include the following 8 lines */I/* Stuart Rance for Alpha port, November 1992 */ #ifdef ALPHA#pragma nostandard#pragma member_alignment __save#pragma nomember_alignment#endif#define __struct variant_struct /*** MODULE $FH1DEF ***/N#define FH1$C_LEVEL1 257 /* 401 octal = structure level 1 */N#define FH1$K_LENGTH 46 /* length of header area */N#define FH1$C_LENGTH 46 /* length of header area */struct FH1DEF {N unsigned char FH1$B_IDOFFSET; /* ident area offset in words */N unsigned char FH1$B_MPOFFSET; /* map area offset in words */ variant_union {N unsigned short int FH1$W_FID [2]; /* file ID */ __struct {N unsigned short int FH1$W_FID_NUM; /* file number */N unsigned short int FH1$W_FID_SEQ; /* file sequence number */ } FH1$R_FID_FIELDS; } FH1$R_FID_OVERLAY;N unsigned short int FH1$W_STRUCLEV; /* file structure level */ variant_union {N unsigned short int FH1$W_FILEOWNER; /* file owner UIC */ __struct {N unsigned char FH1$B_UICMEMBER; /* UIC member number */N unsigned char FH1$B_UICGROUP; /* UIC group number */% } FH1$R_FILEOWNER_FIELDS;" } FH1$R_FILEOWNER_OVERLAY; variant_union {N unsigned short int FH1$W_FILEPROT; /* file protection */ __struct {N unsigned FH1$V_SYSPRO : 4; /* system protection */N unsigned FH1$V_OWNPRO : 4; /* owner protection */N unsigned FH1$V_GROUPPRO : 4; /* group protection */N unsigned FH1$V_WORLDPRO : 4; /* world protection */" } FH1$R_FILEPROT_BITS;! } FH1$R_FILEPROT_O 4t5 $DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2r"VERLAY; variant_union {N unsigned short int FH1$W_FILECHAR; /* file characteristics */ __struct { variant_union {T unsigned char FH1$B_USERCHAR; /* user controlled characteristics */ __struct {[ unsigned FH1$V_WASCONTIG : 1; /* file was (and should be) contiguous */S unsigned FH1$V_NOBACKUP : 1; /* file is not to be backed up */N unsigned FH1DEF$$_FILL_2 : 1; /* reserved */S unsigned FH1$V_READCHECK : 1; /* verify all read operations */T unsigned FH1$V_WRITCHECK : 1; /* verify all write operations */Z unsigned FH1$V_CONTIGB : 1; /* keep file as contiguous as possible */N unsigned FH1$V_LOCKED : 1; /* file is deaccess locked */N unsigned FH1$V_CONTIG : 1; /* file is contiguous */* } FH1$R_USERCHAR_BITS;) } FH1$R_USERCHAR_OVERLAY; variant_union {U unsigned char FH1$B_SYSCHAR; /* system controlled characteristics */ __struct {N unsigned FH1DEF$$_FILL_3 : 4; /* reserved */N unsigned FH1$V_SPOOL : 1; /* intermediate spool file */N unsigned FH1DEF$$_FILL_4 : 1; /* reserved */P unsigned FH1$V_BADBLOCK : 1; /* file contains bad blocks */P unsigned FH1$V_MARKDEL : 1; /* file is marked for delete */) } FH1$R_SYSCHAR_BITS;( } FH1$R_SYSCHAR_OVERLAY;$ } FH1$R_FILECHAR_FIELDS;! } FH1$R_FILECHAR_OVERLAY;N unsigned short int FH1$W_RECATTR [16]; /* file record attributes */N short int FH1DEF$$_FILL_5 [232]; /* rest of file header */N unsigned short int FH1$W_CHECKSUM; /* file header checksum */ } ; /*** MODULE $FI1DEF ***/N#define FI1$K_LENGTH 46 /* length of ident area */N#define FI1$C_LENGTH 46 /* length of ident area */struct FI1DEF {N unsigned short int FI1$W_FILENAME [3]; /* file name (RAD-50) */N unsigned short int FI1$W_FILETYPE; /* file type (RAD-50) */N unsigned short int FI1$W_VERSION; /* version number (binary) */N unsigned short int FI1$W_REVISION; /* revision number (binary) */N char FI1$T_REVDATE [7]; /* revision date (ASCII DDMMMYY) */N char FI1$T_REVTIME [6]; /* revision time (ASCII HHMMSS) */N char FI1$T_CREDATE [7]; /* creation date (ASCII DDMMMYY) */N char FI1$T_CRETIME [6]; /* creation time (ASCII HHMMSS) */N char FI1$T_EXPDATE [7]; /* expiration date (ASCII DDMMMYY) */N char FI1DEF$$_FILL_1; /* dummy byte to round up */N char FI1$T_MTHDR1 [80]; /* HDR1 of ANSI magnetic tape file */N char FI1$T_MTHDR2 [80]; /* HDR2 of ANSI magnetic tape file */N char FI1$T_MTHDR3 [80]; /* HDR3 of ANSI magnetic tape file */ } ; /*** MODULE $FM1DEF ***/N#define FM1$K_POINTERS 10 /* start of retrieval pointers */N#define FM1$C_POINTERS 10 /* start of retrieval pointers */N#define FM1$K_LENGTH 10 /* length of map area */N#define FM1$C_LENGTH 10 /* length of map area */N/* retrieval pointer format */struct FM1DEF {V unsigned char FM1$B_EX_SEGNUM; /* extension segment number of this header */O unsigned char FM1$B_EX_RVN; /* extension relative volume number */N unsigned short int FM1$W_EX_FILNUM; /* extension file number */N unsigned short int FM1$W_EX_FILSEQ; /* extension file sequence number */Q unsigned char FM1$B_COUNTSIZE; /* retrieval pointer count field size */O unsigned char FM1$B_LBNSIZE; /* retrieval pointer LBN field size */O unsigned char FM1$B_INUSE; /* number of retrieval words in use */R unsigned char FM1$B_AVAIL; /* number of retrieval words available */ } ;struct FM1DEF1 {N unsigned char FM1$B_HIGHLBN; /* high order LBN */N unsigned char FM1$B_COUNT; /* block count */N unsigned short int FM1$W_LOWLBN; /* low order LBN */ } ;:struct FM1DEF2 { /* WARNING: aggregate has origin of -4 */! unsigned char FM1$B_PREVHLBN;" unsigned char FM1$B_PREVCOUNT;N unsigned short int FM1$W_PREVLLBN; /* previous retrieval pointer */ char FM1DEF$$_FILL_1; } ; /*** MODULE $FH2DEF ***/N/*+ */N/* */N/* File header definitions for Files-11 Structure Level 2 */N/* */N/*- */N#define FH2$C_LEVEL1 257 /* 401 octal = structure level 1 */N#define FH2$C_LEVEL2 512 /* 1000 octal = structure level 2 */#define FH2$M_VCC_STATE 1792#define FH2$M_ALM_STATE 1835008#define FH2$M_WASCONTIG 1#define FH2$M_NOBACKUP 2#define FH2$M_WRITEBACK 4#define FH2$M_READCHECK 8#define FH2$M_WRITCHECK 16#define FH2$M_CONTIGB 32#define FH2$M_LOCKED 64#define FH2$M_CONTIG 128#define FH2$M_BADACL 2048#define FH2$M_SPOOL 4096#define FH2$M_DIRECTORY 8192#define FH2$M_BADBLOCK 16384#define FH2$M_MARKDEL 32768#define FH2$M_NOCHARGE 65536#define FH2$M_ERASE 131072#define FH2$M_ALM_AIP 262144!#define FH2$M_ALM_ARCHIVED 524288!#define FH2$M_ALM_DELETED 1048576#define FH2$M_ONLY_RU 1#define FH2$M_RUJNL 2#define FH2$M_BIJNL 4#define FH2$M_AIJNL 8#define FH2$M_ATJNL 16#define FH2$M_NEVER_RU 32#define FH2$M_JOURNAL_FILE 64N#define FH2$C_RU_FACILITY_RMS 1 /* RMS */N#define FH2$C_RU_FACILITY_DBMS 2 /* DBMS */N#define FH2$C_RU_FACILITY_RDB 3 /* Rdb/VMS */N#define FH2$C_RU_FACILITY_CHKPNT 4 /* Checkpoint/Restart */N#define FH2$K_LENGTH 80 /* length of header area */N#define FH2$C_LENGTH 80 /* length of header area */N#define FH2$K_SUBSET0_LENGTH 88 /* length of header area */N#define FH2$C_SUBSET0_LENGTH 88 /* length of header area */N#define FH2$K_FULL_LENGTH 108 /* length of full header */N#define FH2$C_FULL_LENGTH 108 /* length of full header */struct FH2DEF {N unsigned char FH2$B_IDOFFSET; /* ident area offset in words */N unsigned char FH2$B_MPOFFSET; /* map area offset in words */R unsigned char FH2$B_ACOFFSET; /* access control list offset in words */N unsigned char FH2$B_RSOFFSET; /* reserved area offset in words */N unsigned short int FH2$W_SEG_NUM; /* file segment number */ variant_union {N unsigned short int FH2$W_STRUCLEV; /* file structure level */ __struct {N unsigned char FH2$B_STRUCVER; /* file structure version */O unsigned char FH2$B_STRUCLEV; /* principal file structure level */$ } FH2$R_STRUCLEV_FIELDS;! } FH2$R_STRUCLEV_OVERLAY; variant_union {N unsigned short int FH2$W_FID [3]; /* file ID */ __struct {N unsigned short int FH2$W_FID_NUM; /* file number */N unsigned short int FH2$W_FID_SEQ; /* file sequence number */ variant_union {O unsigned short int FH2$W_FID_RVN; /* relative volume number */ __struct {N unsigned char FH2$B_FID_RVN; /* alternate format RVN */^ unsigned char FH2$B_FID_NMX; /* alternate format file number extension */+ } FH2$R_FID_RVN_FIELDS;( } FH2$R_FID_RVN_OVERLAY; } FH2$R_FID_FIELDS; } FH2$R_FID_OVERLAY; variant_union {N unsigned short int FH2$W_EXT_FID [3]; /* extension file ID */! ip$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2re." __struct {N unsigned short int FH2$W_EX_FIDNUM; /* extension file number */U unsigned short int FH2$W_EX_FIDSEQ; /* extension file sequence number */ variant_union {[ unsigned short int FH2$W_EX_FIDRVN; /* extension relative volume number */ __struct {X unsigned char FH2$B_EX_FIDRVN; /* alternate format extension RVN */j unsigned char FH2$B_EX_FIDNMX; /* alternate format extension file number extension */- } FH2$R_EX_FIDRVN_FIELDS;* } FH2$R_EX_FIDRVN_OVERLAY;# } FH2$R_EXT_FID_FIELDS; } FH2$R_EXT_FID_OVERLAY;N unsigned short int FH2$W_RECATTR [16]; /* file record attributes */ variant_union {N unsigned long int FH2$L_FILECHAR; /* file characteristics */ __struct {N unsigned FH2DEF$$_FILL_21 : 8; /* reserved */N unsigned FH2$V_VCC_STATE : 3; /* VCC state bits */N unsigned FH2DEF$$_FILL_22 : 7; /* reserved */N unsigned FH2$V_ALM_STATE : 3; /* ALM state bits */& unsigned FH2$V_fill_0 : 3;$ } FH2$R_FILECHAR_CHUNKS; __struct {S unsigned FH2$V_WASCONTIG : 1; /* file was (and should be) contiguous */N unsigned FH2$V_NOBACKUP : 1; /* file is not to be backed up */N unsigned FH2$V_WRITEBACK : 1; /* file may be write-back cached */N unsigned FH2$V_READCHECK : 1; /* verify all read operations */N unsigned FH2$V_WRITCHECK : 1; /* verify all write operations */R unsigned FH2$V_CONTIGB : 1; /* keep file as contiguous as possible */N unsigned FH2$V_LOCKED : 1; /* file is deaccess locked */N unsigned FH2$V_CONTIG : 1; /* file is contiguous */N unsigned FH2DEF$$_FILL_2 : 3; /* reserved */N unsigned FH2$V_BADACL : 1; /* ACL is invalid */N unsigned FH2$V_SPOOL : 1; /* intermediate spool file */N unsigned FH2$V_DIRECTORY : 1; /* file is a directory */N unsigned FH2$V_BADBLOCK : 1; /* file contains bad blocks */N unsigned FH2$V_MARKDEL : 1; /* file is marked for delete */O unsigned FH2$V_NOCHARGE : 1; /* file space is not to be charged */R unsigned FH2$V_ERASE : 1; /* erase file contents before deletion */N unsigned FH2$V_ALM_AIP : 1; /* Archive in progress */N unsigned FH2$V_ALM_ARCHIVED : 1; /* File archived */N unsigned FH2$V_ALM_DELETED : 1; /* File contents deleted */N/* Note: The high 8 bits of this longword */N/* are reserved for user and CSS use. */& unsigned FH2$V_fill_1 : 3;" } FH2$R_FILECHAR_BITS;! } FH2$R_FILECHAR_OVERLAY;N unsigned short int FH2$W_RECPROT; /* record protection */N unsigned char FH2$B_MAP_INUSE; /* number of map area words in use */N unsigned char FH2$B_ACC_MODE; /* least privileged access mode */ variant_union {N unsigned long int FH2$L_FILEOWNER; /* file owner UIC */ __struct {N unsigned short int FH2$W_UICMEMBER; /* UIC member number */N unsigned short int FH2$W_UICGROUP; /* UIC group number */% } FH2$R_FILEOWNER_FIELDS;" } FH2$R_FILEOWNER_OVERLAY;N unsigned short int FH2$W_FILEPROT; /* file protection */ variant_union {N unsigned short int FH2$W_BACKLINK [3]; /* back link pointer */ __struct {N unsigned short int FH2$W_BK_FIDNUM; /* back link file number */U unsigned short int FH2$W_BK_FIDSEQ; /* back link file sequence number */ variant_union {[ unsigned short int FH2$W_BK_FIDRVN; /* back link relative volume number */ __struct {X unsigned char FH2$B_BK_FIDRVN; /* alternate format back link RVN */j unsigned char FH2$B_BK_FIDNMX; /* alternate format back link file number extension */- } FH2$R_BK_FIDRVN_FIELDS;* } FH2$R_BK_FIDRVN_OVERLAY;$ } FH2$R_BACKLINK_FIELDS;! } FH2$R_BACKLINK_OVERLAY; variant_union {N unsigned char FH2$B_JOURNAL; /* journal control flags */ __struct {W unsigned FH2$V_ONLY_RU : 1; /* file is accessible only in recovery unit */N unsigned FH2$V_RUJNL : 1; /* enable recovery unit journal */N unsigned FH2$V_BIJNL : 1; /* enable before image journal */N unsigned FH2$V_AIJNL : 1; /* enable after image journal */N unsigned FH2$V_ATJNL : 1; /* enable audit trail journal */X unsigned FH2$V_NEVER_RU : 1; /* file is never accessible in recovery unit */N unsigned FH2$V_JOURNAL_FILE : 1; /* this is a journal file */& unsigned FH2$V_fill_2 : 1;! } FH2$R_JOURNAL_BITS;S } FH2$R_JOURNAL_OVERLAY;Y unsigned char FH2$B_RU_ACTIVE; /* If non-zero, file has active recovery units */*N/* (value is recoverable facility id number) */N/* 1-99 reserved to DEC, 100-127 reserved for */N/* CSS, 128-255 reserved for customers. */N short int FH2DEF$$_FILL_3; /* reserved */N unsigned long int FH2$L_HIGHWATER; /* high-water mark in file */N long int FH2$L_FILL_6 [2]; /* reserved */P __struct { /* security classification mask */N char FH2$B_FILL_5 [20]; /* see structure in $CLSDEF */ } FH2$R_CLASS_PROT; N char FH2DEF$$_FILL_4 [402]; /* rest of file header */N unsigned short int FH2$W_CHECKSUM; /* file header checksum */ } ;  /*** MODULE $FI2DEF ***/N#define FI2$K_LENGTH 120 /* length of ident area */N#define FI2$C_LENGTH 120 /* length of ident area */struct FI2DEF { S char FI2$T_FILENAME [20]; /* file name, type, and version (ASCII) *//N unsigned short int FI2$W_REVISION; /* revision number (binary) */N unsigned int FI2$Q_CREDATE [2]; /* creation date and time */N unsigned int FI2$Q_REVDATE [2]; /* revision date and time */N unsigned int FI2$Q_EXPDATE [2]; /* expiration date and time */N unsigned int FI2$Q_BAKDATE [2]; /* backup date and time */N char FI2$T_FILENAMEXT [66]; /* extension file name area */N char FI2$T_USERLABEL [80]; /* optional user file label */ } ;; /*** MODULE $FM2DEF ***/N/* retrieval pointer type codes */N#define FM2$C_PLACEMENT 0 /* 00 = placement control data */N#define FM2$C_FORMAT1 1 /* 01 = format 1 */N#define FM2$C_FORMAT2 2 /* 10 = format 2 */N#define FM2$C_FORMAT3 3 /* 11 = format 3 */N/* format of retrieval pointer */N#define FM2$K_LENGTH0 2 /* length of format 0 (placement) */N#define FM2$C_LENGTH0 2 /* length of format 0 (placement) */N#define FM2$K_LENGTH1 4 /* length of format 1 */N#define FM2$C_LENGTH1 4 /* length of format 1 */struct FM2DEF {1 variant_union {iN unsigned short int FM2$W_WORD0; /* first word, of many uses */ __struct { N unsigned FM2DEF$$_FILL_1 : 14; /* type specific data */N unsigned FM2$V_FORMAT : 2; /* format type code */ } FM2$R_WORD0_BITS0; __struct {VN unsigned FM2$V_EXACT : 1; /* exact placement specified */N unsigned FM2$V_ONCYL : 1; /* on cylinder allocation desired */* unsigned FM2DEF$$_FILL_2 : 10;N unsigned FM2$V_LBN : 1; /* use LBN of next map pointer "<$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2r"( */N unsigned FM2$V_RVN : 1; /* place on specified RVN */& unsigned FM2$V_fill_3 : 2; } FM2$R_WORD0_BITS1; __struct { N unsigned FM2DEF$$_FILL_3 : 8; /* low byte described below */N unsigned FM2$V_HIGHLBN : 6; /* high order LBN */& unsigned FM2$V_fill_4 : 2; } FM2$R_WORD0_BITS2; __struct {nN unsigned FM2$V_COUNT2 : 14; /* format 2 & 3 count field */& unsigned FM2$V_fill_5 : 2; } FM2$R_WORD0_BITS3;N unsigned char FM2$B_COUNT1; /* format 1 count field */ } FM2$R_WORD0_OVERLAY;N unsigned short int FM2$W_LOWLBN; /* format 1 low order LBN */ } ;cN#define FM2$K_LENGTH2 6 /* length of format 2 */N#define FM2$C_LENGTH2 6 /* length of format 2 */struct FM2DEF1 { char FM2DEF$$_FILL_4 [2];LN unsigned long int FM2$L_LBN2; /* format 2 LBN (longword) */ } ; N#define FM2$K_LENGTH3 8 /* length of format 3 */N#define FM2$C_LENGTH3 8 /* length of format 3 */struct FM2DEF2 { char FM2DEF$$_FILL_5 [2];1N unsigned short int FM2$W_LOWCOUNT; /* format 3 low order count */N unsigned long int FM2$L_LBN3; /* format 3 LBN (longword) */ } ;O /*** MODULE $FCHDEF ***/N/*+ */N/* */N/* File characteristics bit definitions. These are identical to, and must */N/* track, the bits in FILECHAR above, but are defined relative to the file */N/* characteristics longword instead of relative to the file header. */N/* */N/*- */#define FCH$M_VCC_STATE 1792#define FCH$M_ALM_STATE 1835008f#define FCH$M_WASCONTIG 1/#define FCH$M_NOBACKUP 2#define FCH$M_WRITEBACK 4A#define FCH$M_READCHECK 8#define FCH$M_WRITCHECK 16#define FCH$M_CONTIGB 32#define FCH$M_LOCKED 64 #define FCH$M_CONTIG 128#define FCH$M_BADACL 2048_#define FCH$M_SPOOL 4096#define FCH$M_DIRECTORY 8192#define FCH$M_BADBLOCK 16384#define FCH$M_MARKDEL 32768 #define FCH$M_NOCHARGE 65536#define FCH$M_ERASE 131072#define FCH$M_ALM_AIP 262144!#define FCH$M_ALM_ARCHIVED 524288p!#define FCH$M_ALM_DELETED 1048576 union FCHDEF { long int FCHDEF$$_FILL_1; __struct { N unsigned FCHDEF$$_FILL_31 : 8; /* reserved */N unsigned FCH$V_VCC_STATE : 3; /* VCC state bits */N unsigned FCHDEF$$_FILL_32 : 7; /* reserved */N unsigned FCH$V_ALM_STATE : 3; /* ALM state bits */" unsigned FCH$V_fill_6 : 3; } FCH$R_FILL_1_CHUNKS; __struct {nQ unsigned FCH$V_WASCONTIG : 1; /* file was (and should be) contiguous */dN unsigned FCH$V_NOBACKUP : 1; /* file is not to be backed up */N unsigned FCH$V_WRITEBACK : 1; /* file may be write-back cached */N unsigned FCH$V_READCHECK : 1; /* verify all read operations */N unsigned FCH$V_WRITCHECK : 1; /* verify all write operations */R unsigned FCH$V_CONTIGB : 1; /* keep file as contiguous as possible */N unsigned FCH$V_LOCKED : 1; /* file is deaccess locked */N unsigned FCH$V_CONTIG : 1; /* file is contiguous */N unsigned FCHDEF$$_FILL_3 : 3; /* reserved */N unsigned FCH$V_BADACL : 1; /* ACL is invalid */N unsigned FCH$V_SPOOL : 1; /* intermediate spool file */N unsigned FCH$V_DIRECTORY : 1; /* file is a directory */N unsigned FCH$V_BADBLOCK : 1; /* file contains bad blocks */N unsigned FCH$V_MARKDEL : 1; /* file is marked for delete */N unsigned FCH$V_NOCHARGE : 1; /* file space is not to be charged */R unsigned FCH$V_ERASE : 1; /* erase file contents before deletion */N unsigned FCH$V_ALM_AIP : 1; /* Archive in progress */N unsigned FCH$V_ALM_ARCHIVED : 1; /* File archived */N unsigned FCH$V_ALM_DELETED : 1; /* File contents deleted */N/* Note: The high 8 bits of this longword */N/* are reserved for user and CSS use. */" unsigned FCH$V_fill_7 : 3; } FCH$R_FILL_1_BITS; } ;K /*** MODULE $FJNDEF ***/N/*+ */N/* */N/* File journal control bit definitions. These are identical to, and must */O/* track, the bits in JOURNAL above, but are defined relative to the journal */N/* control byte instead of relative to the file header. */N/* */N/*- */#define FJN$M_ONLY_RU 1T#define FJN$M_RUJNL 2k#define FJN$M_BIJNL 4 #define FJN$M_AIJNL 8E#define FJN$M_ATJNL 16#define FJN$M_NEVER_RU 32 #define FJN$M_JOURNAL_FILE 64Hunion FJNDEF { char FJNDEF$$_FILL_1;a __struct {dW unsigned FJN$V_ONLY_RU : 1; /* file is accessible only in recovery unit */$N unsigned FJN$V_RUJNL : 1; /* enable recovery unit journal */N unsigned FJN$V_BIJNL : 1; /* enable before image journal */N unsigned FJN$V_AIJNL : 1; /* enable after image journal */N unsigned FJN$V_ATJNL : 1; /* enable audit trail journal */W unsigned FJN$V_NEVER_RU : 1; /* file is never accessible in recovery unit */ N unsigned FJN$V_JOURNAL_FILE : 1; /* this is a journal file */" unsigned FJN$V_fill_8 : 1; } FJN$R_FILL_1_BITS; } ;  /*** MODULE $FATDEF ***/N/*+ */N/* */N/* Record attributes area as used by FCS and RMS. */N/* */N/*- */N#define FAT$C_UNDEFINED 0 /* undefined record type */N#define FAT$C_FIXED 1 /* fixed record type */N#define FAT$C_VARIABLE 2 /* variable length */N#define FAT$C_VFC 3 /* variable + fixed control */U#define FAT$C_STREAM 4 /* RMS-11 (DEC traditional) stream format */N#define FAT$C_STREAMLF 5 /* LF-terminated stream format */N#define FAT$C_STREAMCR 6 /* CR-terminated stream format */N#define FAT$C_SEQUENTIAL 0 /* sequential organization */N#define FAT$C_RELATIVE 1 /* relative organization */N#define FAT$C_INDEXED 2 /* indexed organization */N#define FAT$C_DIRECT 3 /* direct organization */#define FAT$M_FORTRANCC 1o#define FAT$M_IMPLIEDCC 2e#define FAT$M_PRINTCC 4/#define FAT$M_NOSPAN 8#define FAT$K_LENGTH 32 #define FAT$C_LENGTH 32estruct FATDEF {  variant_union { N unsigned char FAT$B_RTYPE; /* record type */ __struct { N unsigned FAT$V_RTYPE : 4; /* record type subfield */N unsigned FAT$V_FILEORG : 4; /* file organization */ } FAT$R_RTYPE_BITS;i } FAT$R_RTYPE_OVERLAY; variant_union {HN unsigned char FAT$B_RATTRIB; /* record attributes */ __struct {SN unsigned FAT$V_FORTRANCC : 1; /* Fortran carriage control */N unsigned FAT$V_IMPLIEDCC : 1; /* implied carriage control */N unsigned FAT$V_PRINTCC : 1; /* print file carriage control */N unsigned FAT$V_NOSPAN : 1; /* no spanned records */& unsigned FAT$V_fill_9 #',$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2r\]"9: 4;! } FAT$R_RATTRIB_BITS; } FAT$R_RATTRIB_OVERLAY;N unsigned short int FAT$W_RSIZE; /* record size in bytes */ variant_union {sN unsigned long int FAT$L_HIBLK; /* highest allocated VBN */ __struct {UN unsigned short int FAT$W_HIBLKH; /* high order word */N unsigned short int FAT$W_HIBLKL; /* low order word */! } FAT$R_HIBLK_FIELDS;  } FAT$R_HIBLK_OVERLAY; variant_union {eN unsigned long int FAT$L_EFBLK; /* end of file VBN */ __struct {/N unsigned short int FAT$W_EFBLKH; /* high order word */N unsigned short int FAT$W_EFBLKL; /* low order word */! } FAT$R_EFBLK_FIELDS;C } FAT$R_EFBLK_OVERLAY;N unsigned short int FAT$W_FFBYTE; /* first free byte in EFBLK */N unsigned char FAT$B_BKTSIZE; /* bucket size in blocks */d unsigned char FAT$B_VFCSIZE; /* size in bytes of fixed length control for VFC records */N unsigned short int FAT$W_MAXREC; /* maximum record size in bytes */N unsigned short int FAT$W_DEFEXT; /* default extend quantity */N unsigned short int FAT$W_GBC; /* global buffer count */N short int FATDEF$$_FILL_1 [4]; /* spare */W unsigned short int FAT$W_VERSIONS; /* default version limit for directory file */  } ;F V/*** MODULE $HM1DEF ***/N/*+ */N/* */N/* Home block definitions for Files-11 Structure Level 1 */N/* */N/*- */N#define HM1$C_LEVEL1 257 /* 401 octal = structure level 1 */W#define HM1$C_LEVEL2 258 /* 402 octal = structure level 1, version 2 */2struct HM1DEF {rN unsigned short int HM1$W_IBMAPSIZE; /* index file bitmap size, blocks */N unsigned long int HM1$L_IBMAPLBN; /* index file bitmap starting LBN */N unsigned short int HM1$W_MAXFILES; /* maximum ! files on volume */N unsigned short int HM1$W_CLUSTER; /* storage bitmap cluster factor */N unsigned short int HM1$W_DEVTYPE; /* disk device type */N unsigned short int HM1$W_STRUCLEV; /* volume structure level */N char HM1$T_VOLNAME [12]; /* volume name (ASCII) */N char HM1DEF$$_FILL_1 [4]; /* spare */N unsigned short int HM1$W_VOLOWNER; /* volume owner UIC */ variant_union { N unsigned short int HM1$W_PROTECT; /* volume protection */ __struct { N unsigned HM1$V_SYSPRO : 4; /* system protection */N unsigned HM1$V_OWNPRO : 4; /* owner protection */N unsigned HM1$V_GROUPPRO : 4; /* group protection */N unsigned HM1$V_WORLDPRO : 4; /* world protection */! } HM1$R_PROTECT_BITS;d } HM1$R_PROTECT_OVERLAY;N unsigned short int HM1$W_VOLCHAR; /* volume characteristics */N unsigned short int HM1$W_FILEPROT; /* default file protection */N char HM1DEF$$_FILL_2 [6]; /* spare */N unsigned char HM1$B_WINDOW; /* default window size */N unsigned char HM1$B_EXTEND; /* default file extend */N unsigned char HM1$B_LRU_LIM; /* default LRU limit */N char HM1DEF$$_FILL_3 [11]; /* spare */N unsigned short int HM1$W_CHECKSUM1; /* first checksum */N char HM1$T_CREDATE [14]; /* volume creation date */N char HM1DEF$$_FILL_4 [382]; /* spare */N unsigned long int HM1$L_SERIALNUM; /* pack serial number */N char HM1DEF$$_FILL_5 [12]; /* reserved */N char HM1$T_VOLNAME2 [12]; /* 2nd copy of volume name */N char HM1$T_OWNERNAME [12]; /* volume owner name */N char HM1$T_FORMAT [12]; /* volume format type */N char HM1DEF$$_FILL_6 [2]; /* spare */N unsigned short int HM1$W_CHECKSUM2; /* second checksum */ } ;n H/*** MODULE $HM2DEF ***/N/*+ */N/* */N/* Home block definitions for Files-11 Structure Level 2 */N/* */N/*- */N#define HM2$C_LEVEL1 257 /* 401 octal = structure level 1 */N#define HM2$C_LEVEL2 512 /* 1000 octal = structure level 2 */#define HM2$M_READCHECK 1/#define HM2$M_WRITCHECK 2 #define HM2$M_ERASE 4 #define HM2$M_NOHIGHWATER 8#define HM2$M_CLASS_PROT 16 struct HM2DEF {tN unsigned long int HM2$L_HOMELBN; /* LBN of home (i.e., this) block */N unsigned long int HM2$L_ALHOMELBN; /* LBN of alternate home block */Q unsigned long int HM2$L_ALTIDXLBN; /* LBN of alternate index file header */A variant_union {oN unsigned short int HM2$W_STRUCLEV; /* volume structure level */ __struct { N unsigned char HM2$B_STRUCVER; /* structure version number */N unsigned char HM2$B_STRUCLEV; /* main structure level */$ } HM2$R_STRUCLEV_FIELDS;! } HM2$R_STRUCLEV_OVERLAY;eN unsigned short int HM2$W_CLUSTER; /* storage bitmap cluster factor */N unsigned short int HM2$W_HOMEVBN; /* VBN of home (i.e., this) block */N unsigned short int HM2$W_ALHOMEVBN; /* VBN of alternate home block */Q unsigned short int HM2$W_ALTIDXVBN; /* VBN of alternate index file header */ N unsigned short int HM2$W_IBMAPVBN; /* VBN of index file bitmap */N unsigned long int HM2$L_IBMAPLBN; /* LBN of index file bitmap */N unsigned long int HM2$L_MAXFILES; /* maximum ! files on volume */N unsigned short int HM2$W_IBMAPSIZE; /* index file bitmap size, blocks */N unsigned short int HM2$W_RESFILES; /* ! reserved files on volume */N unsigned short int HM2$W_DEVTYPE; /* disk device type */T unsigned short int HM2$W_RVN; /* relative volume number of this volume */N unsigned short int HM2$W_SETCOUNT; /* count of volumes in set */ variant_union {sN unsigned short int HM2$W_VOLCHAR; /* volume characteristics */ __struct {nN unsigned HM2$V_READCHECK : 1; /* verify all read operations */N unsigned HM2$V_WRITCHECK : 1; /* verify all write operations */N unsigned HM2$V_ERASE : 1; /* erase all files on delete */N unsigned HM2$V_NOHIGHWATER : 1; /* turn off high-water marking */[ unsigned HM2$V_CLASS_PROT : 1; /* enable classification checks on the volume */ ' unsigned HM2$V_fill_10 : 3; ! } HM2$R_VOLCHAR_BITS; } HM2$R_VOLCHAR_OVERLAY;N unsigned long int HM2$L_VOLOWNER; /* volume owner UIC */N unsigned long int HM2$L_SEC_MASK; /* volume security mask */N unsigned short int HM2$W_PROTECT; /* volume protection */N unsigned short int HM2$W_FILEPROT; /* default file protection */N unsigned short int HM2$W_RECPROT; /* default file record protection */N unsigned short int HM2$W_CHECKSUM1; /* first checksum */N unsigned int HM2$Q_CREDATE [2]; /* volume creation date */N unsigned char HM2$B_WINDOW; /* default window size */N unsigned char HM2$B_LRU_LIM; /* default LRU limit */N unsigned short int HM2$W_EXTEND; /* default file extend */N unsigned int HM2$Q_RETAINMIN [2]; /* minimum file retention period */N unsigned int HM2$Q_RETAINMAX [2]; /* maximum file retention period */N unsign$ԕ=$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2rQ"Jed int HM2$Q_REVDATE [2]; /* volume revision date */N struct { /* volume minimum security class */ char HM2$B_FILL_2 [20];  } HM2$R_MIN_CLASS;N struct { /* volume maximum security class */ char HM2$B_FILL_3 [20];* } HM2$R_MAX_CLASS;N unsigned short int HM2$W_FILETAB_FID [3]; /* file lookup table FID */ variant_union { N unsigned short int HM2$W_LOWSTRUCLEV; /* lowest struclev on volume */ __struct { N unsigned char HM2$B_LOWSTRUCVER; /* structure version number */N unsigned char HM2$B_LOWSTRUCLEV; /* main structure level */' } HM2$R_LOWSTRUCLEV_FIELDS;e$ } HM2$R_LOWSTRUCLEV_OVERLAY; variant_union {iO unsigned short int HM2$W_HIGHSTRUCLEV; /* highest struclev on volume */  __struct { N unsigned char HM2$B_HIGHSTRUCVER; /* structure version number */N unsigned char HM2$B_HIGHSTRUCLEV; /* main structure level */( } HM2$R_HIGHSTRUCLEV_FIELDS;% } HM2$R_HIGHSTRUCLEV_OVERLAY;fN char HM2DEF$$_FILL_1 [310]; /* spare */N unsigned long int HM2$L_SERIALNUM; /* pack serial number */N char HM2$T_STRUCNAME [12]; /* structure (volume set name) */N char HM2$T_VOLNAME [12]; /* volume name */N char HM2$T_OWNERNAME [12]; /* volume owner name */N char HM2$T_FORMAT [12]; /* volume format type */N char HM2DEF$$_FILL_2 [2]; /* spare */N unsigned short int HM2$W_CHECKSUM2; /* second checksum */ } ;* C/*** MODULE $DIRDEF ***/N/*+ */N/* */N/* Directory entry structure for Files-11 Structure Level 2 */N/* */N/*- */N#define DIR$C_FID 0 /* normal file ID */N#define DIR$C_LINKNAME 1 /* symbolic name */Q#define DIR$K_LENGTH 6 /* length of directory entry overhead */tQ#define DIR$C_LENGTH 6 /* length of directory entry overhead */ N#define DIR$S_NAME 80 /* maximum length of name string */struct DIRDEF { P unsigned short int DIR$W_SIZE; /* size of directory record in bytes */N unsigned short int DIR$W_VERLIMIT; /* maximum number of versions */ variant_union {CN unsigned char DIR$B_FLAGS; /* status flags */ __struct {eN unsigned DIR$V_TYPE : 3; /* directory entry type */N unsigned DIRDEF$$_FILL_1 : 3; /* reserved */Y unsigned DIR$V_NEXTREC : 1; /* another record of same name & type follows */ Z unsigned DIR$V_PREVREC : 1; /* another record of same name & type precedes */ } DIR$R_FLAGS_BITS;EN/* directory entry type codes */ } DIR$R_FLAGS_OVERLAY; variant_union {/N unsigned char DIR$B_NAMECOUNT; /* byte count of name string */ __struct {H! char DIRDEF$$_FILL_2;sN char DIR$T_NAME []; /* name string */N/* the version numbers and file ID's follow the */N/* variable length name area in the form of a */N/* blockvector. Each entry is as follows: */% } DIR$R_NAMECOUNT_FIELDS; " } DIR$R_NAMECOUNT_OVERLAY; } ; N#define DIR$K_VERSION 8 /* size of each version entry */N#define DIR$C_VERSION 8 /* size of each version entry */struct DIRDEF1 {N short int DIR$W_VERSION; /* version number */ variant_union { N unsigned short int DIR$W_FID [3]; /* file ID */ __struct { N unsigned short int DIR$W_FID_NUM; /* file number */N unsigned short int DIR$W_FID_SEQ; /* file sequence number */ variant_union {fO unsigned short int DIR$W_FID_RVN; /* relative volume number */F __struct {tN unsigned char DIR$B_FID_RVN; /* alternate format RVN */^ unsigned char DIR$B_FID_NMX; /* alternate format file number extension */+ } DIR$R_FID_RVN_FIELDS;a( } DIR$R_FID_RVN_OVERLAY; } DIR$R_FID_FIELDS;* } DIR$R_FID_OVERLAY; } ; union DIRDEF2 {NR char DIR$T_LINKNAME; /* symbolic link name (counted string) */ } ;  /*** MODULE $SCBDEF ***/N/*+ */N/* */N/* Format of storage control block, Files-11 Structure Level 2 */N/* */N/*- */N#define SCB$C_LEVEL2 512 /* 1000 octal = structure level 2 */#define SCB$M_MAPDIRTY 1#define SCB$M_MAPALLOC 2#define SCB$M_FILALLOC 4#define SCB$M_QUODIRTY 8#define SCB$M_HDRWRITE 16#define SCB$M_CORRUPT 32#define SCB$M_MAPDIRTY2 1r#define SCB$M_MAPALLOC2 2d#define SCB$M_FILALLOC2 4 #define SCB$M_QUODIRTY2 8y#define SCB$M_HDRWRITE2 16#define SCB$M_CORRUPT2 32 #define SCB$M_NORMAL 1#define SCB$M_NEW 2#define SCB$M_REBLDNG 4 #define SCB$M_VERIFY 8#define SCB$M_MVBEGUN 16#define SCB$M_COPYING 32#define SCB$M_MERGING 64#define SCB$M_MINIMRG 128f#define SCB$M_CPY_RESET 256E#define SCB$M_BOOTING 512-#define SCB$M_FAILED 32768#define SCB$M_MBR_FCPY 1#define SCB$M_MBR_MERGE 2e#define SCB$M_MBR_CIP 4 #define SCB$M_MBR_MASTER 8#define SCB$M_MBR_ERROR 16#define SCB$M_MBR_SRC 32#define SCB$M_MBR_VALID 128 N#define SCB$K_LENGTH 512 /*Length of Structure */N#define SCB$C_LENGTH 512 /*Length of Structure */struct SCBDEF {d variant_union { N unsigned short int SCB$W_STRUCLEV; /* file structure level */ __struct {nN unsigned char SCB$B_STRUCVER; /* file structure version */O unsigned char SCB$B_STRUCLEV; /* principal file structure level */y$ } SCB$R_STRUCLEV_FIELDS;! } SCB$R_STRUCLEV_OVERLAY;TN unsigned short int SCB$W_CLUSTER; /* storage map cluster factor */N unsigned long int SCB$L_VOLSIZE; /* volume size in logical blocks */Z unsigned long int SCB$L_BLKSIZE; /* number of physical blocks per logical block */N unsigned long int SCB$L_SECTORS; /* number of sectors per track */N unsigned long int SCB$L_TRACKS; /* number of tracks per cylinder */N unsigned long int SCB$L_CYLINDER; /* number of cylinders */ variant_union {PN unsigned long int SCB$L_STATUS; /* volume status flags */ __struct {nX unsigned SCB$V_MAPDIRTY : 1; /* storage map is dirty (partially updated) */Y unsigned SCB$V_MAPALLOC : 1; /* storage map is preallocated (lost blocks) */*a unsigned SCB$V_FILALLOC : 1; /* file numbers are preallocated (lost header slots) */ W unsigned SCB$V_QUODIRTY : 1; /* quota file is dirty (partially updated) */iR unsigned SCB$V_HDRWRITE : 1; /* file headers are write back cached */N unsigned SCB$V_CORRUPT : 1; /* file structure is corrupt */' unsigned SCB$V_fill_11 : 2;a } SCB$R_STATUS_BITS; } SCB$R_STATUS_OVERLAY;i variant_union { [ unsigned long int SCB$L_STATUS2; /* backup status - bits must match those above */  __struct { Y unsigned SCB$V_MAPDIRTY2 : 1; /* storage map is dirty (partially updated) */_Z unsigned SCB$V_MAPALLOC2 : 1; /* storage map is preallocated (lost blocks) */b unsigned SCB$V_FILALLOC2 : 1; /* file numbers are preallocated (lost header slots) */X unsign%m8$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2r"[ed SCB$V_QUODIRTY2 : 1; /* quota file is dirty (partially updated) */S unsigned SCB$V_HDRWRITE2 : 1; /* file headers are write back cached */ N unsigned SCB$V_CORRUPT2 : 1; /* file structure is corrupt */' unsigned SCB$V_fill_12 : 2;i! } SCB$R_STATUS2_BITS;r } SCB$R_STATUS2_OVERLAY;N unsigned short int SCB$W_WRITECNT; /* count of write access mounters. */` char SCB$T_VOLOCKNAME [12]; /* name used for file system serialization on volume. */N unsigned int SCB$Q_MOUNTTIME [2]; /* time of last initial mount. */N unsigned short int SCB$W_BACKREV; /* BACKUP revision number. */N unsigned int SCB$Q_GENERNUM [2]; /* shadow set revision number. */N unsigned int SCB$Q_UNIT_ID [2]; /* Virtual Unit specifier */ variant_union {N unsigned short int SCB$W_SHADOW_STATUS; /* Volume status: */ __struct {2N unsigned SCB$V_NORMAL : 1; /* Shadow set populated and online */N unsigned SCB$V_NEW : 1; /* Newly created, no members yet */N unsigned SCB$V_REBLDNG : 1; /* rebuilding shadow set */N unsigned SCB$V_VERIFY : 1; /* This SS needs verification */N unsigned SCB$V_MVBEGUN : 1; /* Mount verification initiated */N unsigned SCB$V_COPYING : 1; /* Full copy in progreess */N unsigned SCB$V_MERGING : 1; /* Merge copy in progress */N unsigned SCB$V_MINIMRG : 1; /* Mini-merge in progress */N unsigned SCB$V_CPY_RESET : 1; /* Copy mode is reset. */N unsigned SCB$V_BOOTING : 1; /* Shadow set in booting state */N unsigned SCB$v_filler : 5; /* Reserve one last field */N unsigned SCB$V_FAILED : 1; /* Shadow set not populated */' } SCB$R_SHADOW_STATUS_BITS;u& } SCB$R_SHADOW_STATUS_OVERLAY; union {sN unsigned char SCB$B_MEMBER_STATUS; /* Member status bytes */ __struct { N unsigned SCB$V_MBR_FCPY : 1; /* Member involved in copy */N unsigned SCB$V_MBR_MERGE : 1; /* Member being merged */N unsigned SCB$V_MBR_CIP : 1; /* Copy (or merge) in progress */O unsigned SCB$V_MBR_MASTER : 1; /* Member with guaranteed correct */N/* SCB. Same member as MEMBERSHIP_LOCK */N unsigned SCB$V_MBR_ERROR : 1; /* Error processing in progress */N unsigned SCB$V_MBR_SRC : 1; /* member can be used for source */N unsigned SCB$v_filler : 1; /* Reserve one last field */N unsigned SCB$V_MBR_VALID : 1; /* Status information is valid */' } SCB$R_MEMBER_STATUS_BITS;** } SCB$R_MEMBER_STATUS_OVERLAY [3];N char SCB$b_filler [3]; /* Reserved for alignment */N unsigned int SCB$Q_MEMBER_IDS [2] [3]; /* Unit ID for member */N unsigned long int SCB$L_SCB_LBN; /* Unit Control Block for VU */N unsigned char SCB$B_DEVICES; /* Number of devices in SS */N unsigned char SCB$B_MEMBERS; /* Number of full members */N unsigned char SCB$B_MAST_INDX; /* Array index to master UCB */N unsigned char SCB$B_MRG_TARGETS; /* Merge Copy Targets */N unsigned char SCB$B_FC_TARGETS; /* Full Copy Targets */X char SCB$b_shadow_reserved [84]; /* reserved for expansion to 10 units per set */N char SCB$b_reserved [313]; /* reserved */N unsigned short int SCB$W_CHECKSUM; /* block checksum */ } ;  /*** MODULE $BBMDEF ***/N/*+ */N/* */N/* Bad block map (generated by bad block scan program) */N/* */N/*- */N#define BBM$K_POINTERS 4 /* start of retrieval pointers */N#define BBM$C_POINTERS 4 /* start of retrieval pointers */struct BBMDEF {fQ unsigned char BBM$B_COUNTSIZE; /* retrieval pointer count field size */ O unsigned char BBM$B_LBNSIZE; /* retrieval pointer LBN field size */*O unsigned char BBM$B_INUSE; /* number of retrieval words in use */LR unsigned char BBM$B_AVAIL; /* number of retrieval words available */N char BBMDEF$$_FILL_1 [506]; /* pointer space */N unsigned short int BBM$W_CHECKSUM; /* block checksum */N/* retrieval pointer format */ } ; struct BBMDEF1 {N unsigned char BBM$B_HIGHLBN; /* high order LBN */N unsigned char BBM$B_COUNT; /* block count */N unsigned short int BBM$W_LOWLBN; /* low order LBN */ } ;V:struct BBMDEF2 { /* WARNING: aggregate has origin of -4 */! unsigned char BBM$B_PREVHLBN; " unsigned char BBM$B_PREVCOUNT;N unsigned short int BBM$W_PREVLLBN; /* previous retrieval pointer */ char BBMDEF$$_FILL_2;  } ;  e/*** MODULE $BBDDEF ***/N/*+ */N/* */N/* Bad block descriptor (generated by formatters for RK06, RM03, et al) */N/* */N/*- */N#define BBD$K_DESCRIPT 8 /* start of bad block descriptors */N#define BBD$C_DESCRIPT 8 /* start of bad block descriptors */struct BBDDEF { N unsigned long int BBD$L_SERIAL; /* pack serial number */N unsigned short int BBD$W_RESERVED; /* reserved area (MBZ) */V unsigned short int BBD$W_FLAGS; /* pack status flags (zero for normal use) */ char BBDDEF$$_FILL_1 [500]; N unsigned long int BBD$L_LASTWORD; /* last longword of block */ } ;d#define BBD$K_ENTRY 4/#define BBD$C_ENTRY 4 union BBDDEF1 {uN unsigned long int BBD$L_BADBLOCK; /* individual bad block entry */ __struct {MN unsigned BBD$V_CYLINDER : 15; /* cylinder number of bad block */% unsigned BBDDEF$$_FILL_2 : 1; N unsigned BBD$V_SECTOR : 8; /* sector number of bad block */N unsigned BBD$V_TRACK : 7; /* track number of bad block */# unsigned BBD$V_fill_13 : 1;  } BBD$R_BADBLOCK_BITS; } ;t t/*** MODULE $VSLDEF ***/N/*+ */N/* */N/* Structure of a volume set list file entry. Record 1 contains the volume */P/* set name. Record n+1 contains the volume label of RVN n in the volume set. */N/* */N/*- */#define VSL$K_LENGTH 64 #define VSL$C_LENGTH 64Qstruct VSLDEF { N char VSL$T_NAME [12]; /* volume name */N char VSLDEF$$_FILL_1 [52]; /* unused */ } ;  i/*** MODULE $PBBDEF ***/N/*+ */N/* */N/* Pending bad block file record format. Each record describes a disk block */N/* on which an error has occurred which has not been turned over to the bad */N/* block file. */N/* */N/*- */#define PBB$M_READERR 1$#define PBB$M_WRITERR 2 N#define PBB$K_LENGTH 16 /* length of entry */N#define PBB$C_LENGTH 16 /* length of entry */struct PBBDEF {iN unsigned short int PBB$W_FID [3]; /* File ID of containing file */ &:;i`$DISKBLOCK055.D/W]fJ)[RANCE.DISKBLOCK.KIT055.SOURCE]F11DEF.H;2r" l variant_union {TN unsigned char PBB$B_FLAGS; /* status flags */ __struct {IN unsigned PBB$V_READERR : 1; /* read error occurred */N unsigned PBB$V_WRITERR : 1; /* write error occurred */' unsigned PBB$V_fill_14 : 6;C } PBB$R_FLAGS_BITS;( } PBB$R_FLAGS_OVERLAY;N unsigned char PBB$B_COUNT; /* error count */N unsigned long int PBB$L_VBN; /* virtual block in file */N unsigned long int PBB$L_LBN; /* logical block number */ } ;$ I/*** MODULE $DQFDEF ***/N/*+ */N/* */Q/* Structure of disk quota file record. Each record contains the authorization */ N/* and usage of a particular UIC for this volume set. */N/* */N/*- */#define DQF$M_ACTIVE 1#define DQF$K_LENGTH 32 #define DQF$C_LENGTH 32nstruct DQFDEF {  variant_union {rN unsigned long int DQF$L_FLAGS; /* flags longword, containing... */ __struct { N unsigned DQF$V_ACTIVE : 1; /* record contains an active entry */' unsigned DQF$V_fill_15 : 7;  } DQF$R_FLAGS_BITS;o } DQF$R_FLAGS_OVERLAY;N unsigned long int DQF$L_UIC; /* UIC of this record */N unsigned long int DQF$L_USAGE; /* number of blocks in use */N unsigned long int DQF$L_PERMQUOTA; /* permanent disk quota */N unsigned long int DQF$L_OVERDRAFT; /* overdraft limit */N long int DQFDEF$$_FILL_1 [3]; /* reserved */ } ; #ifdef ALPHA"#pragma member_alignment __restore#pragma standard#endif#endif**[RANCE.DISKBLOCK.KIT055.SOURCE]HANDLER.C;2+,W/. / 4P -fJ0123KPWO 5 6;z-7duK!8dv*9G HJ#include "diskblock.h"Mextern short output_flag, /* Indicates RMS file open for SEARCH/OUTPUT */M log_flag; /* Indicates RMS file open for SET LOG */@long out_file(struct dsc$descriptor *line_descrip, int *actprm);@long log_file(struct dsc$descriptor *line_descrip, int *actprm);2int handler( int *signal_arr, int *mechanism_arr ){P int status, /* VMS return status */P actprm; /* Action routine parameter */7 long (*actrtn)(struct dsc$descriptor *line_descrip); M /* Resignal Faults that would result in an infinite loop if we continue */) if ((signal_arr[1] == SS$_DEBUG) || ' (signal_arr[1] == SS$_ACCVIO) ||% (signal_arr[1] == SS$_TBIT) ||' (signal_arr[1] == SS$_OPCCUS) ||' (signal_arr[1] == SS$_OPCDEC) ||% (signal_arr[1] == SS$_ROPRAND)) return(SS$_RESIGNAL); if (log_flag!=0) {O actrtn = &log_file; /* SET LOG command has been issued */O actprm = 1; /* Messages to file and sys$output */ }  elseO actrtn = NULL; /* Messages to sys$output only */ O if (output_flag != 0) /* /OUTPUT was specified for a command */ { actrtn = &out_file;' if (signal_arr[1] == &DSKB_FOUND)P actprm = 0; /* FOUND message is sent to file only */ elseP actprm = 1; /* Other messages to file and sys$output */ } P signal_arr[0] -= 2; /* PC and PSL are not wanted... */7 status = SYS$PUTMSG(&signal_arr[0],actrtn,0,actprm);P signal_arr[0] += 2; /* Restore original signal array */ return(SS$_CONTINUE);} ?long log_file(struct dsc$descriptor *line_descrip, int *actprm){P extern struct FAB logfab; /* File attributes block */P extern struct RAB lograb; /* Record attributes block */ int status;P lograb.rab$l_rbf = line_descrip->dsc$a_pointer; /* Buffer address for PUTs */P lograb.rab$w_rsz = line_descrip->dsc$w_length; /* Record size for PUTs */! status = SYS$PUT(&lograb,0,0);$ if (!$VMS_STATUS_SUCCESS(status))9 printf("Fatal error writing log file, status = %d", logfab.fab$l_stv); elseP log_flag = 3; /* 1 = file open, 3 = data in buffers */P return actprm; /* 1 = print message to sys$output, 0 = done */} ?long out_file(struct dsc$descriptor *line_descrip, int *actprm){P extern struct FAB outfab; /* File attributes block */P extern struct RAB outrab; /* Record attributes block */ int status;P outrab.rab$l_rbf = line_descrip->dsc$a_pointer; /* Buffer address for PUTs */P outrab.rab$w_rsz = line_descrip->dsc$w_length; /* Record size for PUTs */( if ( (log_flag!=0) && (actprm == 1) )$ log_file(line_descrip,actprm); ! status = SYS$PUT(&outrab,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {@ printf("\nFatal error writing output file, status = %d\n", outfab.fab$l_stv);N return 1; /* Force message to be sent to SYS$OUTPUT */ } elseN output_flag = 3; /* 1 = file open, 3 = data in buffers */N return actprm; /* 1 = print message to sys$output, 0 = done */} '*[RANCE.DISKBLOCK.KIT055.SOURCE]HELP.C;2+,X;./ 4P0-fJ0123KPWO5 6<7|-7S!8&v*9G HJ#include "diskblock.h"J#include /* Symbols used by LBR$OUTPUT_HELP */J#include /* Defines LRB$OUTPUT_HELP procedure */void help_request(void){& const long HELP$_OPENIN = 0x76109A;M extern struct dsc$descriptor_s help_logical; /* Help Library name */M extern const char define_help; /* Message when no library */+ const $DESCRIPTOR(topic_param, "TOPIC");> const unsigned long help_flags = HLP$M_PROMPT | HLP$M_HELP;P unsigned long status; /* VMS return status */P char topic[1024]; /* Topic entered with HELP at DISKBLOCK prompt*/! $DESCRIPTOR(topic_desc,topic);K status=cli$get_value(&topic_param,&topic_desc,&topic_desc.dsc$w_length);B if ( ($VMS_STATUS_SUCCESS(status)) || (status == CLI$_ABSENT) ) { status = LBR$OUTPUT_HELP(O &put_output, /* Output routine */O 0, /* Default output width (80) */A &topic_desc, /* Help request line */A &help_logical, /* Name of help library */A &help_flags, /* */A &get_input /* Input routine */ ); }F if ($VMS_STATUS_MSG_NO(status) == $VMS_STATUS_MSG_NO(HELP$_OPENIN))H if (!$VMS_STATUS_SUCCESS(status=print_line(&define_help))) return; else; if (!$VMS_'BR$DISKBLOCK055.DX;fJ'[RANCE.DISKBLOCK.KIT055.SOURCE]HELP.C;2PSTATUS_SUCCESS(status)) lib$signal(status);}/*[RANCE.DISKBLOCK.KIT055.SOURCE]INSTRUCTIONS.C;2+,PXS.'/ 4O''R-fJ0123KPWO(5 6暑7K_!82v*9G HJ#include "diskblock.h"<void decode_inst( union ALPHA_INST *instruction, char *line){; void intreg( union ALPHA_INST *instruction, char *line);: void broff( union ALPHA_INST *instruction, char *line);F void memreg( union ALPHA_INST *instruction, char *line, char type); switch (instruction->opcode) { case 0x00:  {& switch (instruction->palcode) {2 /* Privileged PAL code instructions */C case 0x0000: {sprintf(line,"PAL HALT " ); break;}C case 0x0001: {sprintf(line,"PAL CFLUSH " ); break;}C case 0x0002: {sprintf(line,"PAL DRAINA " ); break;}C case 0x0003: {sprintf(line,"PAL LDQP " ); break;}C case 0x0004: {sprintf(line,"PAL STQP " ); break;}C case 0x0005: {sprintf(line,"PAL SWPCTX " ); break;}C case 0x0006: {sprintf(line,"PAL MFPR_ASN " ); break;}A case 0x0007: {sprintf(line,"PAL MTPR_ASTEN"); break;}C case 0x0008: {sprintf(line,"PAL MTPR_ASTSR" ); break;}C case 0x000B: {sprintf(line,"PAL MFPR_FEN " ); break;}C case 0x000C: {sprintf(line,"PAL MTPR_FEN " ); break;}C case 0x000D: {sprintf(line,"PAL MTPR_IPIR " ); break;}C case 0x000E: {sprintf(line,"PAL MFPR_IPL " ); break;}C case 0x000F: {sprintf(line,"PAL MTPR_IPL " ); break;}C case 0x0010: {sprintf(line,"PAL MFPR_ICES " ); break;}C case 0x0011: {sprintf(line,"PAL MTPR_MCES " ); break;}C case 0x0012: {sprintf(line,"PAL MFPR_PCBB " ); break;}C case 0x0013: {sprintf(line,"PAL MFPR_PRBR " ); break;}C case 0x0014: {sprintf(line,"PAL MTPR_PRBR " ); break;}C case 0x0015: {sprintf(line,"PAL MFPR_PTBR " ); break;}C case 0x0016: {sprintf(line,"PAL MFPR_SCBB " ); break;}C case 0x0017: {sprintf(line,"PAL MTPR_SCBB " ); break;}C case 0x0018: {sprintf(line,"PAL MTPR_SIRR " ); break;}C case 0x0019: {sprintf(line,"PAL MFPR_SISR " ); break;}C case 0x001A: {sprintf(line,"PAL MFPR_TBCHK" ); break;}C case 0x001B: {sprintf(line,"PAL MTPR_TBIA " ); break;}C case 0x001C: {sprintf(line,"PAL MTPR_TBIAP" ); break;}C case 0x001D: {sprintf(line,"PAL MTPR_TBIS " ); break;}C case 0x001E: {sprintf(line,"PAL MFPR_ESP " ); break;}C case 0x001F: {sprintf(line,"PAL MTPR_ESP " ); break;}C case 0x0020: {sprintf(line,"PAL MFPR_SSP " ); break;}C case 0x0021: {sprintf(line,"PAL MTPR_SSP " ); break;}C case 0x0022: {sprintf(line,"PAL MFPR_USP " ); break;}C case 0x0023: {sprintf(line,"PAL MTPR_USP " ); break;}C case 0x0024: {sprintf(line,"PAL MTPR_TBISD" ); break;}C case 0x0025: {sprintf(line,"PAL MTPR_TBISI" ); break;}C case 0x0026: {sprintf(line,"PAL MFPR_ASTEN" ); break;}C case 0x0027: {sprintf(line,"PAL MFPR_ASTSR" ); break;}C case 0x0029: {sprintf(line,"PAL MFPR_VTPB " ); break;}C case 0x002A: {sprintf(line,"PAL MTPR_VTPB " ); break;}C case 0x002B: {sprintf(line,"PAL MTPR_PERFMON"); break;}C case 0x002E: {sprintf(line,"PAL MTPR_DATFX" ); break;}C case 0x003F: {sprintf(line,"PAL MFPR_WHAMI" ); break;}4 /* Unprivileged PAL code instructions */? case 0x0080: {sprintf(line,"PAL BPT " ); break;}? case 0x0081: {sprintf(line,"PAL BUGCHK" ); break;}? case 0x0082: {sprintf(line,"PAL CHME " ); break;}? case 0x0083: {sprintf(line,"PAL CHMK " ); break;}? case 0x0084: {sprintf(line,"PAL CHMS " ); break;}? case 0x0085: {sprintf(line,"PAL CHMU " ); break;}? case 0x0086: {sprintf(line,"PAL IMB " ); break;}? case 0x0087: {sprintf(line,"PAL INSQHIL" ); break;}? case 0x0088: {sprintf(line,"PAL INSQTIL" ); break;}? case 0x0089: {sprintf(line,"PAL INSQHIQ" ); break;}? case 0x008A: {sprintf(line,"PAL INSQTIQ" ); break;}? case 0x008B: {sprintf(line,"PAL INSQUEL" ); break;}? case 0x008C: {sprintf(line,"PAL INSQUEQ" ); break;}@ case 0x008D: {sprintf(line,"PAL INSQUEL/D"); break;}@ case 0x008E: {sprintf(line,"PAL INSQUEQ/D"); break;}? case 0x008F: {sprintf(line,"PAL PROBER" ); break;}? case 0x0090: {sprintf(line,"PAL PROBEW" ); break;}? case 0x0091: {sprintf(line,"PAL RD_PS " ); break;}? case 0x0092: {sprintf(line,"PAL REI " ); break;}? case 0x0093: {sprintf(line,"PAL REMQHIL" ); break;}? case 0x0094: {sprintf(line,"PAL REMQTIL" ); break;}? case 0x0095: {sprintf(line,"PAL REMQHIQ" ); break;}? case 0x0096: {sprintf(line,"PAL REMQTIQ" ); break;}? case 0x0097: {sprintf(line,"PAL REMQUEL" ); break;}? case 0x0098: {sprintf(line,"PAL REMQUEQ" ); break;}@ case 0x0099: {sprintf(line,"PAL REMQUEL/D"); break;}@ case 0x009A: {sprintf(line,"PAL REMQUEQ/D"); break;}? case 0x009B: {sprintf(line,"PAL SWASTEN" ); break;}? case 0x009C: {sprintf(line,"PAL WR_PS_SW"); break;}? case 0x009D: {sprintf(line,"PAL RSCC " ); break;}? case 0x009E: {sprintf(line,"PAL READ_UNQ"); break;}@ case 0x009F: {sprintf(line,"PAL WRITE_UNQ"); break;}C default : sprintf(line, "PAL %d",instruction->palcode); }; break; } case 0x08:  {" sprintf(line,"LDA ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x09:  {" sprintf(line,"LDAH ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x0B:  {# sprintf(line,"LDQ_U "); O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x0F:  {" sprintf(line,"STQ_U ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x10:  {I switch (instruction->I_func) /* Integer Arithmetic Functions */ {: case 0x00 : {sprintf(line, "ADDL "); break;}: case 0x02 : {sprintf(line, "S4ADDL "); break;}: case 0x09 : {sprintf(line, "SUBL "); break;}: case 0x0b : {sprintf(line, "S4SUBL "); break;}: case 0x0F : {sprintf(line, "CMPBGE "); break;}: case 0x12 : {sprintf(line, "S8ADDL "); break;}: case 0x1b : {sprintf(line, "S8SUBL "); break;}: case 0x1d : {sprintf(line, "CMPULT "); break;}: case 0x20 : {sprintf(line, "ADDQ "); break;}: case 0x22 : {sprintf(line, "S4ADDQ "); break;}: case 0x29 : {sprintf(line, "SUBQ "); break;}: case 0x2b : {sprintf(line, "S4SUBQ "); break;}: case 0x2d : {sprintf(line, "CMPEQ "); break;}: case 0x32 : {sprintf(line, "S8ADDQ "); break;}: case 0x3b : {sprintf(line, "S8SUBQ "); break;}: case 0x3d : {sprintf(line, "CMPULE "); break;}: case 0x40 : {sprintf(line, "ADDL/V "); break;}: case 0x49 : {sprintf(line, "SUBL/V "); break;}: case(]h$DISKBLOCK055.DPXSfJ/[RANCE.DISKBLOCK.KIT055.SOURCE]INSTRUCTIONS.C;2O'" 0x4d : {sprintf(line, "CMPLT "); break;}: case 0x60 : {sprintf(line, "ADDQ/V "); break;}: case 0x69 : {sprintf(line, "SUBQ/V "); break;}: case 0x6d : {sprintf(line, "CMPLE "); break;}9 default : {sprintf(line, "Unknown INTA*");} };I intreg(instruction, line); /* Add integer registers to line */ break;< } /* End of Integer Arithmetic functions */ case 0x11:  {F switch (instruction->I_func) /* Integer Logical Functions */ {: case 0x00 : {sprintf(line, "AND "); break;}: case 0x08 : {sprintf(line, "BIC "); break;}: case 0x14 : {sprintf(line, "CMOVLBS"); break;}: case 0x16 : {sprintf(line, "CMOVLBC"); break;}: case 0x20 : {sprintf(line, "BIS "); break;}: case 0x24 : {sprintf(line, "CMOVEQ "); break;}: case 0x26 : {sprintf(line, "CMOVNE "); break;}: case 0x28 : {sprintf(line, "ORNOT "); break;}: case 0x40 : {sprintf(line, "XOR "); break;}: case 0x44 : {sprintf(line, "CMOVLT "); break;}: case 0x48 : {sprintf(line, "EQV "); break;}: case 0x46 : {sprintf(line, "CMOVEGE"); break;}: case 0x64 : {sprintf(line, "CMOVLE "); break;}: case 0x66 : {sprintf(line, "CMOVGT "); break;}9 default : {sprintf(line, "Unknown INTL*");} };I intreg(instruction, line); /* Add integer registers to line */ break; } case 0x12:  {G switch (instruction->I_func) /* Integer Subtract Functions */ {: case 0x02 : {sprintf(line, "MSKBL "); break;}: case 0x06 : {sprintf(line, "EXTBL "); break;}: case 0x0b : {sprintf(line, "INSBL "); break;}: case 0x12 : {sprintf(line, "MSKWL "); break;}: case 0x16 : {sprintf(line, "EXTWL "); break;}: case 0x1b : {sprintf(line, "INSWL "); break;}: case 0x22 : {sprintf(line, "MSKLL "); break;}: case 0x26 : {sprintf(line, "EXTLL "); break;}: case 0x2b : {sprintf(line, "INSLL "); break;}: case 0x30 : {sprintf(line, "ZAP "); break;}: case 0x31 : {sprintf(line, "ZAPNOT "); break;}: case 0x32 : {sprintf(line, "MSKQL "); break;}: case 0x34 : {sprintf(line, "SRL "); break;}: case 0x36 : {sprintf(line, "EXTQL "); break;}: case 0x39 : {sprintf(line, "SLL "); break;}: case 0x3b : {sprintf(line, "INSQL "); break;}: case 0x3c : {sprintf(line, "SRA "); break;}: case 0x52 : {sprintf(line, "MSKWH "); break;}: case 0x57 : {sprintf(line, "INSWH "); break;}: case 0x5a : {sprintf(line, "EXTWH "); break;}: case 0x62 : {sprintf(line, "MSKLH "); break;}: case 0x67 : {sprintf(line, "INSLH "); break;}: case 0x6a : {sprintf(line, "EXTLH "); break;}: case 0x72 : {sprintf(line, "MSKQH "); break;}: case 0x77 : {sprintf(line, "INSQH "); break;}: case 0x7a : {sprintf(line, "EXTQH "); break;}9 default : {sprintf(line, "Unknown INTS*");} };I intreg(instruction, line); /* Add integer registers to line */ break; } case 0x13:  {G switch (instruction->I_func) /* Integer Multiply Functions */ {: case 0x00 : {sprintf(line, "MULL "); break;}: case 0x20 : {sprintf(line, "MULQ "); break;}; case 0x30 : {sprintf(line, "UMULQ "); break;}: case 0x40 : {sprintf(line, "MULLHV "); break;}: case 0x60 : {sprintf(line, "MULQ/V "); break;}9 default : {sprintf(line, "Unknown INTM*");} };I intreg(instruction, line); /* Add integer registers to line */ break; } case 0x15:  {4 sprintf(line,"FLTV* F%d",instruction->Fa);  break; } case 0x16:  {4 sprintf(line,"FLTI* F%d",instruction->Fa);  break; } case 0x17:  {4 sprintf(line,"FLTL* F%d",instruction->Fa);  break; } case 0x18:  { sprintf(line,"MISC*");  break; } case 0x19:  case 0x1B:  case 0x1D:  case 0x1E:  {' sprintf(line,"Reserved PAL");  break; } case 0x1A:  { char temp[80];N switch (instruction->mem_br_type) /* Memory Format Branch Opcodes */ {; case 0x00 : {sprintf(line, "JMP "); break;}; case 0x01 : {sprintf(line, "JSR "); break;}; case 0x02 : {sprintf(line, "RET "); break;}A case 0x03 : {sprintf(line, "JSR_COROUTINE "); break;}D default : {sprintf(line,"Unknown JSR* instruction ");} };N sprintf(temp,"R%d, R%d, (HINT %d)", instruction->Ra, instruction->Rb,F instruction->mem_br_displ); strcat(line, temp); break; } case 0x20:  {" sprintf(line,"LDF ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x21:  {" sprintf(line,"LDG ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x22:  {" sprintf(line,"LDS ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x23:  {" sprintf(line,"LDT ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x24:  {" sprintf(line,"STF ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x25:  {" sprintf(line,"STG ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x26:  {" sprintf(line,"STS ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x27:  {" sprintf(line,"STT ");O memreg(instruction, line, 'F'); /* Add memory registers and offset */ break; } case 0x28:  {" sprintf(line,"LDL ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x29:  {" sprintf(line,"LDQ ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2A:  {" sprintf(line,"LDL_L ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2B:  {" sprintf(line,"LDQ_L ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2C:  {" sprintf(line,"STL ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2D:  {" sprintf(line,"STQ ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2E:  {" sprintf(line,"STL_C ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x2F:  {" sprintf(line,"STQ_C ");O memreg(instruction, line, 'R'); /* Add memory registers and offset */ break; } case 0x30:  {# sprintf(line,"BR R");D broff(instruction, line); /* Add Branch offset to line */ break; } case 0x31:  {# sprintf(line,"FBEQ F");D broff(instruction, line); /* Add Branch offset to line */ break; } case 0x32:  {# sprintf(line,"FBLT F");D broff(instruction, line); /* Add Branch offset to line */ break; } case 0x33:  {# sprintf(line,"FBLE F");D)w$DISKBLOCK055.DPXSfJ/[RANCE.DISKBLOCK.KIT055.SOURCE]INSTRUCTIONS.C;2O'5! broff(instruction, line); /* Add Branch offset to line */ break;n }  case 0x34:  {T# sprintf(line,"BSR R"); D broff(instruction, line); /* Add Branch offset to line */ break;n }, case 0x35:  { # sprintf(line,"FBNE F");D broff(instruction, line); /* Add Branch offset to line */ break;  }P case 0x36:  {n# sprintf(line,"FBGE F");tD broff(instruction, line); /* Add Branch offset to line */ break;H }  case 0x37:  {0# sprintf(line,"FBGT F");)D broff(instruction, line); /* Add Branch offset to line */ break;  }e case 0x38:  {T# sprintf(line,"BLBC R");aD broff(instruction, line); /* Add Branch offset to line */ break;t }A case 0x39:  { # sprintf(line,"BEQ R");"D broff(instruction, line); /* Add Branch offset to line */ break;  } case 0x3A:  {i# sprintf(line,"BLT R");D broff(instruction, line); /* Add Branch offset to line */ break;e }{ case 0x3B:  { # sprintf(line,"BLE R");:D broff(instruction, line); /* Add Branch offset to line */ break;A }L case 0x3C:  { # sprintf(line,"BLBS R");RD broff(instruction, line); /* Add Branch offset to line */ break;; }  case 0x3D:  {i# sprintf(line,"BNE R"); D broff(instruction, line); /* Add Branch offset to line */ break;1 }t case 0x3E:  {r# sprintf(line,"BGE R");iD broff(instruction, line); /* Add Branch offset to line */ break;R }) case 0x3F:  {0# sprintf(line,"BGT R"); D broff(instruction, line); /* Add Branch offset to line */ break;  }a default:  { 1 sprintf(line,"Reserved Instruction" ); { break;  }K }}a7void intreg( union ALPHA_INST *instruction, char *line) $/* This routine will format the */$/* Rn, Rn, Rn or */$/* Rn, #nnn, Rn */$/* Part of an integer instruction */{char temp[80];" if (instruction->lit_flag == 0)$ sprintf(temp," R%d, R%d, R%d",9 instruction->Ra, instruction->Rb, instruction->Rc);  else0& sprintf(temp, " R%d, #%d, R%d", > instruction->Ra, instruction->literal, instruction->Rc); ) strcat(line, temp);}e6void broff( union ALPHA_INST *instruction, char *line)4/* This routine will format the offset and */4/* register number part of a branch instruction */{Tchar temp[80];B sprintf(temp,"%d, %d", instruction->Ra, instruction->br_displ); strcat(line, temp);}0Bvoid memreg( union ALPHA_INST *instruction, char *line, char type)2/* This routine will format the offset and */2/* register number part of a memory instruction */{)char temp[80];9 sprintf(temp,"%c%d, %d(%c%d)", type, instruction->Ra, a9 instruction->mem_displ,M9 type, instruction->Rb);  strcat(line, temp);}%*[RANCE.DISKBLOCK.KIT055.SOURCE]IO.C;2+,WX.'/ 4V'%-fJ0123KPWO(5 6}-7Dsh!8D;v*9G HJ#include "diskblock.h"L#include /* Screen Management routines */L#include /* and status returns */Kstatic unsigned short line_number; /* Used by GET_INPUT and PUT_OUTPUT */K /* to enable */Nint get_time(struct dsc$descriptor_s *param, /* Parameter name */N unsigned int *quadword) /* Quadword VMS date time */{1 unsigned long status; /* VMS status return */> char temp_data[132]; /* Storage for quadword date time */* $DESCRIPTOR(temp_data_desc, temp_data); status=cli$get_value(M param, /* Parameter name */M &temp_data_desc, /* Returned string */M &temp_data_desc.dsc$w_length /* Returned length */ );L if (!$VMS_STATUS_SUCCESS(status)) return status; /* No data from DCL */1 status = SYS$BINTIM(&temp_data_desc,quadword);$ if (!$VMS_STATUS_SUCCESS(status))4 LIB$SIGNAL(&DSKB_INVTIME,1,&temp_data_desc,0); return status;} Oint get_integer(struct dsc$descriptor_s *param, /* Parameter name */O unsigned long max_data, /* maximum allowed value */O unsigned long *address) /* Address for returned data */K/* This routine will fetch the integer specified by CLI parameter param */I/* it will check that the integer is <= max_data and will generate an */I/* error message if it is too large. It will return the integer value *//* in address. */&/* Return value 0 indicates failure */&/* Return value 1 indicates success */{5 unsigned long status, /* VMS status return */ temp_value;  N char temp_data[32]; /* Storage for string representation of integer */) $DESCRIPTOR(temp_data_desc,temp_data); status=cli$get_value(M param, /* Parameter name */M &temp_data_desc, /* Returned string */M &temp_data_desc.dsc$w_length /* Returned length */ );L if (!$VMS_STATUS_SUCCESS(status)) return status; /* No data from DCL */  H /* Routine OTS$CVT_TI_L converts signed integer text to an integer */6 status = OTS$CVT_TI_L(&temp_data_desc,&temp_value);$ if (!$VMS_STATUS_SUCCESS(status)) {= LIB$SIGNAL(&DSKB_INVNUMBER,1,&temp_data_desc,status,0);5 return 0; /* Unable to convert to an integer */ }  4 if ( (temp_value > max_data) && (max_data != 0) ) {> LIB$SIGNAL(&DSKB_NUMBIG,3,temp_value,param,max_data); return 0; }  *address = temp_value; return 1;} $unsigned long print_line(char *line){L/* This routine will use printf to print the given line on sys$output */L/* If an output file is open the line will be sent there instead */L/* If a logfile is open the text line will be sent there as well */P extern unsigned short log_flag, /* 1=File open, 3=data in buffer */P output_flag, /* 1=File open, 3=data in buffer */P term_flag; /* 1 = SYS$OUTPUT is a terminal */P extern struct RAB lograb; /* Record attributes block */P extern struct RAB outrab; /* Record attributes block */7 extern const struct dsc$descriptor_s cr_to_continue;P unsigned long status; /* VMS Status Return */P unsigned short i; /* Loop counter */ /* Check for output file */ if (output_flag!=0) { outrab.rab$l_rbf = line;J outrab.rab$w_rsz = strlen(line)-1; /* Don't print the \n */$ status = SYS$PUT(&outrab,0,0);' if (!$VMS_STATUS_SUCCESS(status))7 LIB$SIGNAL(&DSKB_LOGERROR,1,outrab.rab$l_stv); else output_flag = 3;  return status; } A /*Add the number of \n characters in the line to line_number*/" for (i=0; line[i] != '\0'; i++)) if (line[i] == '\n') line_number++; 0 if ( (line_number > 22) && (term_flag == 1) ) { char unused[3] = " ";U struct dsc$descriptor_s unused_dsc = {3, DSC$K_DTYPE_T, DSC$K_CLASS_S, unused}; line_n*#:V$DISKBLOCK055.DWXfJ%[RANCE.DISKBLOCK.KIT055.SOURCE]IO.C;2V': " umber = 0;V status = lib$get_input(&unused_dsc, &cr_to_continue,&(unused_dsc.dsc$w_length));7 if (!$VMS_STATUS_SUCCESS(status)) return status; } /* Check for log file */ if (log_flag!=0) { lograb.rab$l_rbf = line;J lograb.rab$w_rsz = strlen(line)-1; /* Don't print the \n */$ status = SYS$PUT(&lograb,0,0);' if (!$VMS_STATUS_SUCCESS(status))7 LIB$SIGNAL(&DSKB_LOGERROR,1,lograb.rab$l_stv); else log_flag = 3; }  printf("%s",line), status=1; return status;}H/***********************************************************************I * PUT_OUTPUT: This routine has identical parameters to LIB$PUT_OUTPUT *I ***********************************************************************/=unsigned long put_output(struct dsc$descriptor_s *out_string){ char out_line[512];I memcpy(out_line, out_string->dsc$a_pointer, out_string->dsc$w_length);- out_line[out_string->dsc$w_length] = '\n';/ out_line[out_string->dsc$w_length+1] = '\0'; return print_line(&out_line);} H/***********************************************************************H * GET_INPUT: This routine has identical parameters to LIB$GET_INPUT *H * and is called by CLI$DCL_PARSE. It uses SMG terminal I/O to enable *H * command line recall. *I ***********************************************************************/unsigned long get_input (L struct dsc$descriptor_s *in_string, /* Descriptor for returned string */L struct dsc$descriptor_s *prompt, /* Descriptor for prompt */L unsigned short *len /* Returned string length */ ){static unsigned long L kb_id=0, /* SMG Virtual Keyboard ID */L kt_id=0; /* SMG Virtual Keytable ID */Lextern unsigned short log_flag; /* 1 = SET LOG file is open */Lextern struct FAB logfab; /* File attributes block */Lextern struct RAB lograb; /* Record attributes block */Lunsigned long status,status1; /* VMS return status */ if (kb_id == 0) {N /***********************************************************************N * Set up the SMG$ keytable and virtual keyboard. *O ***********************************************************************/ 4 status = smg$create_virtual_keyboard(&kb_id);( if (!$VMS_STATUS_SUCCESS(status)) {, LIB$SIGNAL(&DSKB_NOKB,0,status,0); exit(0); } - status = smg$create_key_table(&kt_id);( if (!$VMS_STATUS_SUCCESS(status)) {, LIB$SIGNAL(&DSKB_NOKT,0,status,0); exit(0); }  } C line_number = 0; /* Reset line number every time we do input */ J status=smg$read_composed_line(&kb_id, &kt_id, in_string, prompt, len);, if (status == SMG$_EOF) status=RMS$_EOF;> else if (!$VMS_STATUS_SUCCESS(status)) LIB$SIGNAL(status); if (log_flag != 0) {% char line[512]; ? memcpy(line,prompt->dsc$a_pointer,prompt->dsc$w_length);* memcpy(&line[prompt->dsc$w_length],A in_string->dsc$a_pointer, in_string->dsc$w_length); lograb.rab$l_rbf = line;I lograb.rab$w_rsz = prompt->dsc$w_length + in_string->dsc$w_length;& status1 = SYS$PUT(&lograb,0,0);) if (!$VMS_STATUS_SUCCESS(status1))8 LIB$SIGNAL(&DSKB_LOGERROR,1,logfab.fab$l_stv); elseF log_flag = 3; /* 1 = file open, 3 = data in buffers */ }  return(status);}void rms_flush_ast(int reqidt){O extern int fifteen_secs[2]; /* VMS Quadword for 30 seconds */O extern int flush_efn; /* EFN used for $SETIMR */O extern unsigned short output_flag; /* 1 = file open, 3 = data in buff */O extern struct FAB outfab; /* File attributes block */O extern struct NAM outnam; /* Name block */O extern struct RAB outrab; /* Record attributes block */O extern unsigned short log_flag; /* 1 = file open, 3 = data in buff */O extern struct FAB logfab; /* File attributes block */O extern struct NAM lognam; /* Name block */O extern struct RAB lograb; /* Record attributes block */O unsigned long status; /* VMS Status return */A status = sys$setimr(flush_efn,fifteen_secs,rms_flush_ast,0,0);# if(!$VMS_STATUS_SUCCESS(status))/ LIB$SIGNAL(&DSKB_FLUSHTIMERR,0,status,0);H if (output_flag==3) /* 1 = log file open, 3 = data in buffers */ {L /* We could get errors if the RAB is busy, just ignore them and the */L /* next flush in 15 seconds time will sort everything out. */& status = sys$flush(&outrab,0,0);& if ($VMS_STATUS_SUCCESS(status))8 output_flag = 1; /* Buffers now empty */ } if (log_flag == 3) {L /* We could get errors if the RAB is busy, just ignore them and the */L /* next flush in 15 seconds time will sort everything out. */& status = sys$flush(&lograb,0,0);& if ($VMS_STATUS_SUCCESS(status))5 log_flag = 1; /* Buffers now empty */ }}"unsigned long yes_no(char *prompt){P char return_data[132]; /* User response data */P $DESCRIPTOR(return_desc, return_data); /* Descriptor for user response */P unsigned short length; /* Length of returned string */P struct dsc$descriptor_s p_desc; /* Descriptor for the prompt string */P int status, /* VMS return status */P done, /* 1 = yes or no entered */P return_status; /* 1 = YES, 0 = NO */! p_desc.dsc$a_pointer = prompt;) p_desc.dsc$w_length = strlen(prompt);( p_desc.dsc$b_dtype = DSC$K_DTYPE_T;( p_desc.dsc$b_class = DSC$K_CLASS_S; done = 0; status = 0;8 while ( (done==0) || (!$VMS_STATUS_SUCCESS(status)) ) {9 status = get_input(&return_desc, &p_desc, &length);' if (!$VMS_STATUS_SUCCESS(status)) LIB$SIGNAL(status,0); else {B if ( (return_data[0] == 'N') || (return_data[0] == 'n') ) { return_status = 0; done = 1; } else {E if ( (return_data[0] == 'Y') || (return_data[0] == 'y') ) {! return_status = 1; done = 1; } } } } return return_status;} void open_output(void){Lextern unsigned short output_flag; /* 1 = file open, 3 = data in buff */(const $DESCRIPTOR(output_qual,"OUTPUT");Ounsigned long status; /* VMS status return */O output_flag = 0; /* Assume /NOOUTPUT */& status = CLI$PRESENT(&output_qual);# if ($VMS_STATUS_SUCCESS(status)) {P extern struct FAB outfab; /* File attributes block */P extern struct NAM outnam; /* Name block */P extern struct RAB outrab; /* Record attributes block */P extern char outfilespec[]; /* Full filename returned by RMS */O char file_name[NAM$C_MAXRSS]; /* File name entered by user */O unsigned long filename_size; /* Length of input filename */O $DESCRIPTOR(file_desc,file_name); /* Input filename descriptor */ B const char default_filespec[] = "SYS$SCRATCH:DISKBLOCK.LIS"; % /* Initialise the FAB block */ outfab = cc$rms_fab;P outfab.fab$l_dna = &default_filespec[0]; /* Default filespec */P outfab.fab$b_dns = sizeof(default_filespec); /* Default filespec size */P outfab.fab$b_fac = FAB$M_PUT & FAB$M_GET; /* Going to read/write */P outfab.fab$l_fop = FAB$M_TEF & FAB$M_SQO; /* Truncate file on close */P /* Sequential operations only */P outfab.fab$l_nam = &outnam; /* Address of na+5$DISKBLOCK055.DWXfJ%[RANCE.DISKBLOCK.KIT055.SOURCE]IO.C;2V'me block */P outfab.fab$b_org = FAB$C_SEQ; /* Sequential file */P outfab.fab$b_rat = FAB$M_CR; /* Carriage return per record */P outfab.fab$b_rfm = FAB$C_VAR; /* Variable size records */P outfab.fab$b_shr = FAB$M_SHRGET; /* Allow simultaneous reads */P outfab.fab$w_mrs = 132; /* Max Record size 132 bytes */$ /* Initialise the NAM block */ outnam = cc$rms_nam;M outnam.nam$l_rsa = &outfilespec; /* Full filename at this address */O outnam.nam$b_rss = NAM$C_MAXRSS; /* max size of full filename */ $ /* Initialise the RAB block */ outrab = cc$rms_rab;S outrab.rab$l_fab = &outfab; /* FAB address */S outrab.rab$b_rac = RAB$C_SEQ; /* Sequential access */ P file_desc.dsc$w_length = NAM$C_MAXRSS; /* Max input filename length */ status=cli$get_value(O &output_qual, /* Parameter name */O &file_desc, /* Returned string */O &file_desc.dsc$w_length /* Returned length */ );& if ($VMS_STATUS_SUCCESS(status)) {P /* Get the length and address of the filename string into the fab... */J STR$ANALYZE_SDESC(&file_desc, &filename_size, &outfab.fab$l_fna);* outfab.fab$b_fns = filename_size; }' status = SYS$CREATE(&outfab,0,0);' if (!$VMS_STATUS_SUCCESS(status))D LIB$SIGNAL(&DSKB_CREATERR,1,&file_desc,outfab.fab$l_stv,0); else {L /* The file has been successfully created, connect record stream */+ status = SYS$CONNECT(&outrab,0,0);* if (!$VMS_STATUS_SUCCESS(status))F LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,outfab.fab$l_stv,0); else {O /* Everything worked, put out info message with the new filename */J LIB$SIGNAL(&DSKB_CREATED,2,outnam.nam$b_rsl,outnam.nam$l_rsa); output_flag = 1; }6 } /* End of Output file successfully created */6 } /* End of /OUTPUT qualifier present */6} /* End of open_output */void close_output(void){O extern unsigned short output_flag; /* 1 = file open, 3 = data in buff */ if (output_flag!=0) {O extern struct FAB outfab; /* File attributes block */O extern struct NAM outnam; /* File name block */O unsigned long status; /* VMS status return */& status = SYS$CLOSE(&outfab,0,0);' if (!$VMS_STATUS_SUCCESS(status))F LIB$SIGNAL(&DSKB_CLOSERR,2,outnam.nam$b_rsl,outnam.nam$l_rsa, outfab.fab$l_stv,0); output_flag = 0; }}void control_t(void){B/* This routine is called whenever a control T is typed. */B/* It is called at AST level and so just sets a flag to allow */B/* The interrupted thread to display output at a suitable time. */' extern unsigned short controlt_flag;s controlt_flag = 1;;}*void control_c(void){TA/* This routine is called whenever a control C is typed. */CA/* It is called at AST level and so just sets a flag to allow */,A/* The interrupted thread to exit at a suitable time. */wA/* It also needs to re-enable control C interrupts. */o% extern unsigned short ast_channel;cK int ast_iosb[2], /* I/O status block for ^C */mK status; /* VMS return status */a const int contc_function K = IO$_SETMODE|IO$M_CTRLCAST; /* Function code for ^C */  e' extern unsigned short controlc_flag;  controlc_flag = 1;_' /* Re-enable Control C interrupts */ M status = SYS$QIOW(0, /* Event Flag Number */ M ast_channel, /* I/O channel */VM contc_function, /* I/O function code */;M ast_iosb, /* I/O status block address */_M 0, /* AST Address */aM 0, /* AST Parameter */dM &control_c, /* P1, Control C AST address */tM 0, /* P2, not used */eM 0, /* P3, not used */gM 0, /* P4, not used */ M 0, /* P5, not used */eM 0); /* P6, not used */ 9 if ($VMS_STATUS_SUCCESS(status)) status = ast_iosb[0];r$ if (!$VMS_STATUS_SUCCESS(status))+ LIB$SIGNAL(&DSKB_NOCON_C,0,status,0); }a"void addchar(char *line, char add){a int len;  len = strlen(line); line[len] = add;  line[len+1] = '\0';}a-*[RANCE.DISKBLOCK.KIT055.SOURCE]MESSAGES.MSG;2+,X. / 4P -fJ0123KPWO 5 6lf{i-7dp!8dCv*9G HJ %.title MESSAGES Diskblock Messages.ident /Version 5.4/.facility DSKB,1/prefix=DSKB_.severity informationEBLKMODIF /FAO=2ABLKREAD /FAO=2GBUFMOD KBUFNOTMOD BCHKCHANGED /FAO=2CCHKINVALID /FAO=2/CHKVALID /FAO=1<CONTROL_C /FAO=23CONTROL_T /FAO=2;COPYING /FAO=2?CPYATTRIB /FAO=1?CPYACL /FAO=2%CREATED /FAO=2,DESEL /FAO=19DISKSEL /FAO=2DEXTFID /FAO=1?FACTOR /FAO=2AFID_FFFF 9FILESEL /FAO=2FILENAME /FAO=2PFORCEDERR /FAO=2@FOUND /FAO=46INDEXFMAP 4LASTBLOCK /FAO=1.LASTFID /FAO=2'LOGCLOSE /FAO=2;LOGFILE /FAO=2/NOCON_C /NOCON_T 'NOSEL 2NOTACCES +RESTORED /FAO=2-SEARCHDONE /FAO=1@SEARCHING /FAO=4<SKIPHDR /FAO=1;SPIRALREAD +WRTENAB .severity warningANOEXTHDR /FAO=1NOFILES 6NOTERMCHAN +NYI <RDBADHEADER /FAO=2*WRTBADHEADER <FIRST100 BINVBACKLINK /ACLERR .severity errorGADDRBIG
/FAO=27ASNERR /FAO=1"BADHEADER +CLOSERR /FAO=2,CREATERR /FAO=1KDATABIG /FAO=19DSNERR /FAO=1?DVIERR /FAO=17FIDTOOBIG /FAO=1 ;FLUSHTIMERR /FAO=1/GETERR /FAO=2.HBLKINVCHK1 .HBLKINVCHK2 3HDRINVACOFF /HDRINVCHK CHDRINVFID 3HDRINVIDOFF 3HDRINVMAP 3HDRINVMPOFF 3HDRINVRSOFF 8HDRINVSTRLEV +HDRINVSTRVER 'HOMEBLOCKERR .INDXHDRERR BINSVIRMEM INVFID =INVNUMBER /FAO=1;INVTIME /FAO=18LBNCOUNTERR :LOGERROR /FAO=1(NOBLOCK 5NOBLOCKS %NOFID0 $NOFILENAME $NOINDEXF -NOTDISK /FAO=1DNOTFILE 7NOTFOR /FAO=1.NOTMNT /FAO=18NOTOWNER /FAO=1%NOVBN0 'NO_COUNT0 ENUMBIG /FAO=3+OPENERR /FAO=1/PUTERR /FAO=2,READERR /FAO=1)SPAWNERR GSTRBIG /FAO=1*STRTOOLONG /FAO=1,WRITERR /FAO=1*WRTPROT 9WR_OR_DES .severity fatal&EFERR >JPIERR -NOKB %NOKT .end-*[RANCE.DISKBLOCK.KIT055.SOURCE]READ_WRITE.C;2+,X ./ 4P*-fJ0123KPWO5 6O-7w!85Kv*9G HJ#include "diskblock.h"#define MSCP$M_MD_ERROR 0x1000Pextern unsigned char rw_buff[512]; /* Main READ/WRITE buffer */Pextern struct dsc$descriptor_s real_dev_desc; /* Selected disk/file name */Pextern short protect_flag; /* 1 = select /NOWRITE */Pextern const char carry_on[]; /* "Do you want to continue? */void write_block(void){ if (protect_flag == 1)" LIB$SIGNAL(&DSKB_WRTPROT,0); else {! read_or_write(rw_buff,1,0); }}void rewrite_block(void){O extern unsigned short access_flag; /* 1 = drive has been accessed */ if (protect_flag == 1)" LIB$SIGNAL(&DSKB_WRTPROT,0); else { if (access_flag == 0)& LIB$SIGNAL(&DSKB_NOTACCES,0); else {$ read_or_write(rw_buff,1,1); } }}void read_block(void){ read_or_write(rw_buff,0,0);}Lunsigned long read_or_write( /* This routine does all the work... */L char *buffer, /* Buffer to use */L short write_flag, /* 0 = READ, 1 = WRITE */M short rewrite_flag /* 1 = REWRITE, 0 = READ or WRITE */  ){O extern unsigned long max_block, /* Used for checking user LBN/VBN */O last_block, /* Records last LBN/VBN accessed */O last_fid; /* Records last FID accessed */ extern unsigned shortP disk_channel, /* Channel for Disk or File I/O */P modify_flag, /* 1 = I/O buffer has been modified */P access_flag, /* 1 = Selected drive/file has been accessed */P file_flag; /* 1 = File selected, 0 = Disk selected */P unsigned long status, /* VMS status return */P iosb[2], /* VMS I/O status block */P function, /* VMS I/O function code */P block, /* LBN/VBN to be written */P fid, /* FID to be read/written */P P5; /* P2 paramater for QIO call */P $DESCRIPTOR(blk_param, "BLOCK"); /* CLI parameter name */P $DESCRIPTOR(fe_qual,"FORCED_ERROR"); /* CLI qualifier */P $DESCRIPTOR(fid_qual,"FID"); /* CLI qualifier */P $DESCRIPTOR(check_qual,"CHECKSUM"); /* CLI qualifier */ if (disk_channel == 0) {K /* Print No disk or file selected and immediately return to caller */ LIB$SIGNAL(&DSKB_NOSEL,0); return 0; } if (rewrite_flag == 1) { block = last_block; fid = last_fid; } M else /* Get the new LBN/VBN/FID from the command line and validate it */ {& status = CLI$PRESENT(&fid_qual);' if ( $VMS_STATUS_SUCCESS(status)) {0 /* Get the FID from the command line */8 status = get_integer(&fid_qual,max_block,&fid);9 if (!$VMS_STATUS_SUCCESS(status)) return status;( /* Convert the FID to an LBN */3 if (fid_to_lbn(fid,&block) == 0) return 0; } else7 { /* Get the LBN / VBN from the command line */ fid = 0;; status = get_integer(&blk_param,max_block,&block);* if (!$VMS_STATUS_SUCCESS(status)) {C if (status == CLI$_ABSENT) LIB$SIGNAL(&DSKB_NOBLOCK,0); return 0; } }  }  if (file_flag == 1) {K /* If this is file I/O we must check for an invalid block number */K /* of 0 before setting the function code to show Virtual I/O */ if (block == 0) {$ LIB$SIGNAL(&DSKB_NOVBN0,0); return 0; } else { if (write_flag == 1)% function = IO$_WRITEVBLK; else$ function = IO$_READVBLK; } }C else /* Not File I/O so this must be Logical I/O to a disk */ { if (write_flag == 1) function = IO$_WRITELBLK; else function = IO$_READLBLK; }N if ( (write_flag==1) && $VMS_STATUS_SUCCESS(status=CLI$PRESENT(&fe_qual)) ) {, function = function | IO$M_MSCPMODIFS; P5 = MSCP$M_MD_ERROR; -$DISKBLOCK055.DX fJ-[RANCE.DISKBLOCK.KIT055.SOURCE]READ_WRITE.C;2PQ } else P5 = 0; if (write_flag == 1) {( status = CLI$PRESENT(&check_qual);' if ( $VMS_STATUS_SUCCESS(status))/ checksum_buffer(buffer,TRUE,510,TRUE); if (fid != 0) {( status = check_header(&buffer);* if (!$VMS_STATUS_SUCCESS(status)) {6 LIB$SIGNAL(&DSKB_WRTBADHEADER,0,status,0);( status = (yes_no(carry_on));> if (!$VMS_STATUS_SUCCESS(status)) return status; } } } K status = SYS$QIOW(0, /* Event Flag Number */K disk_channel, /* I/O channel */K function, /* I/O function code */K iosb, /* I/O status block address */K 0, /* AST Address */K 0, /* AST Parameter */K buffer, /* P1, buffer address */K 512, /* P2, buffer size */K block, /* P3, LBN */K 0, /* P4, not used */K P5, /* MSCP_MODIFIERS */K 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];J /* Success and Forced Error both mean the disk has been read/written */F if ( ($VMS_STATUS_SUCCESS(status)) || (status == SS$_FORCEDERROR) ) {J last_block = block; /* Remember last successful I/O */J last_fid = fid; /* Remember whether it was /FID */J modify_flag = 0; /* Buffer has not been modified */J access_flag = 1; /* Disk has been accessed */ if (write_flag == 0)/ { /* Successful read, or Forced Error */' if (status == SS$_FORCEDERROR)? LIB$SIGNAL(&DSKB_FORCEDERR,2,block,&real_dev_desc); else {< LIB$SIGNAL(&DSKB_BLKREAD,2,block,&real_dev_desc); if (fid != 0) {- status = check_header(buffer);0 if (!$VMS_STATUS_SUCCESS(status))E LIB$SIGNAL(&DSKB_RDBADHEADER,2,fid,block,status,0); else {3 char full_filename[NAM$C_MAXRSS],! line[132];D status = fid_to_name(fid,&full_filename,&block,0);2 if ($VMS_STATUS_SUCCESS(status)) {= sprintf(line,"FID: %8d LBN %8d %s\n", < fid,block,full_filename);H if (!$VMS_STATUS_SUCCESS(status=print_line(line))) ' return status; } } } } }" else /* Successful write */; LIB$SIGNAL(&DSKB_BLKMODIF,2,block,&real_dev_desc); }. else /* There was a Read or Write error */ { if (write_flag == 1)4 LIB$SIGNAL(&DSKB_WRITERR,1,block,status,0); else 4 LIB$SIGNAL(&DSKB_READERR,1,block,status,0); }}Aunsigned long fid_to_lbn(unsigned long fid, unsigned long *block){ extern unsigned longM index_lbn[150], /* Starting LBN for this extent */M index_cnt[150], /* Blocks in this extent */M index_tot[150], /* Blocks in this + earlier extents */M vbn_factor; /* Cluster_size*4 + bitmapsize */5 unsigned short i; /* Loop counter */  if (index_cnt[0] == 0) {# LIB$SIGNAL(&DSKB_NOINDEXF,0); return 0; } if (fid == 0) { LIB$SIGNAL(&DSKB_NOFID0); return 0; }  *block = fid + vbn_factor; for (i=0 ; i<=150 ; i++) { if (index_cnt[i] == 0) {A LIB$SIGNAL(&DSKB_FIDTOOBIG,1,index_tot[i] - vbn_factor); return 0; } ! if (index_tot[i] >= *block) {= *block = *block + index_lbn[i] - index_tot[i-1] - 1; return 1; }  } return 0;}0unsigned long read_header(char *buffer, int lbn){ extern unsigned shortJ disk_channel; /* Channel for Disk or File I/O */ unsigned longJ status, /* VMS return status */J iosb[2]; /* $QIO I/O status block *// unsigned long const function = IO$_READLBLK;K status = SYS$QIOW(0, /* Event Flag Number */K disk_channel, /* I/O channel */K function, /* I/O function code */K iosb, /* I/O status block address */K 0, /* AST Address */K 0, /* AST Parameter */K buffer, /* P1, buffer address */K 512, /* P2, buffer size */K lbn, /* P3, LBN */K 0, /* P4, not used */K 0, /* P5, not used */K 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];3 if (!$VMS_STATUS_SUCCESS(status)) return status;! status = check_header(buffer);3 if (!$VMS_STATUS_SUCCESS(status)) return status; return 1;}/unsigned long check_header(struct FH2DEF *buff){" unsigned long highwater_offset;F highwater_offset = (char *)(&buff->FH2$L_HIGHWATER) - (char *)buff;1 if (buff->FH2$B_IDOFFSET < highwater_offset/2) return &DSKB_HDRINVIDOFF;3 if (buff->FH2$B_IDOFFSET > buff->FH2$B_MPOFFSET) return &DSKB_HDRINVMPOFF;3 if (buff->FH2$B_MPOFFSET > buff->FH2$B_ACOFFSET) return &DSKB_HDRINVACOFF; 3 if (buff->FH2$B_ACOFFSET > buff->FH2$B_RSOFFSET) return &DSKB_HDRINVRSOFF;! if (buff->FH2$B_STRUCLEV != 2) return &DSKB_HDRINVSTRLEV;! if (buff->FH2$B_STRUCVER == 0) return &DSKB_HDRINVSTRVER;N if (buff->FH2$B_MAP_INUSE > (buff->FH2$B_ACOFFSET - buff->FH2$B_MPOFFSET) ) return &DSKB_HDRINVMAP; if (buff->FH2$W_FID_NUM == 0) return &DSKB_HDRINVFID;0 if (checksum_buffer(buff,FALSE,510,FALSE)==0) return &DSKB_HDRINVCHK; return 1;}/*[RANCE.DISKBLOCK.KIT055.SOURCE]SAVE_RESTORE.C;2+,X].*/ 4S*)-fJ0123KPWO+5 6d-7D݀!8D]Tv*9G HJK/* save_restore.c */K/* These routines implement the SAVE and RESTORE commands in diskblock */#include "diskblock.h"Pextern unsigned char rw_buff[512]; /* Main READ/WRITE buffer */Pextern unsigned long max_block; /* Used for checking user LBN */Pextern unsigned short file_flag, /* 1 = File selected, 0 = Disk selected */P controlc_flag, /* 1 = control C has been entered */P disk_channel; /* NON 0 shows disk or file selected */Pstatic struct FAB fab; /* File attributes block */Pstatic struct NAM nam; /* Name block */Pstatic struct RAB rab; /* Record attributes block */Pstatic struct XABALL xab; /* eXtended Attributes */Cstatic const char default_filespec[] = "SYS$SCRATCH:DISKBLOCK.DMP";-static const $DESCRI.n$DISKBLOCK055.DX]fJ/[RANCE.DISKBLOCK.KIT055.SOURCE]SAVE_RESTORE.C;2S* "PTOR(file_param, "FILE");Sstatic const $DESCRIPTOR(block_qual,"BLOCK"); /* CLI qualifier */Sstatic const $DESCRIPTOR(start_qual,"BLOCK.START"); /* CLI qualifier */Sstatic const $DESCRIPTOR(end_qual,"BLOCK.END"); /* CLI qualifier */Sstatic const $DESCRIPTOR(cnt_qual,"BLOCK.COUNT"); /* CLI qualifier */Pstatic char file_name[NAM$C_MAXRSS]; /* File name entered by user */(static $DESCRIPTOR(file_desc,file_name);Pstatic char full_filespec[NAM$C_MAXRSS]; /* Full filename returned by RMS */static unsigned long P filename_size, /* Length of input filename */P status; /* VMS status return */Pstatic int end_blk,start_blk,blk_count; /* Blocks to save or restore */5static int save_range(int start_blk, int next_count, I struct FAB *fab, struct RAB *rab, struct NAM *nam);8static int restore_range(int start_blk, int next_count, I struct FAB *fab, struct RAB *rab, struct NAM *nam); void get_filespec(void){B/* This routine is called by both SAVE and RESTORE */B/* It initialises all of the RMS data structures and gets the */B/* input filename (if any) from the DCL command parser */" /* Initialise the FAB block */ fab = cc$rms_fab;P fab.fab$l_dna = &default_filespec[0]; /* Default filespec */P fab.fab$b_dns = sizeof(default_filespec); /* # Bytes in default filespec */P fab.fab$l_nam = &nam; /* Address of expanded name bloc */P fab.fab$b_org = FAB$C_SEQ; /* Sequential file */P fab.fab$b_rfm = FAB$C_FIX; /* Fixed size records */P fab.fab$w_mrs = 512; /* Record size 512 bytes */$ ! /* Initialise the NAM block */ nam = cc$rms_nam;P nam.nam$l_rsa = &full_filespec; /* Full filename wanted at this address */P nam.nam$b_rss = NAM$C_MAXRSS; /* maximum size of full filename */! /* Initialise the RAB block */ rab = cc$rms_rab;P rab.rab$l_fab = &fab; /* FAB address */P rab.rab$b_rac = RAB$C_SEQ; /* Sequential access */P rab.rab$l_rbf = &rw_buff; /* Buffer address for PUTs */P rab.rab$w_rsz = 512; /* Record size for PUTs */P rab.rab$l_ubf = &rw_buff; /* Buffer address for GETs */P rab.rab$w_usz = 512; /* Record size for GETs */P file_desc.dsc$w_length = NAM$C_MAXRSS; /* Maximum input filename length */ status=cli$get_value(O &file_param, /* Parameter name */O &file_desc, /* Returned string */O &file_desc.dsc$w_length /* Returned length */! );# if ($VMS_STATUS_SUCCESS(status)) {P /* Get the length and address of the filename string into the fab... */D STR$ANALYZE_SDESC(&file_desc, &filename_size, &fab.fab$l_fna);$ fab.fab$b_fns = filename_size; } else { if (status == CLI$_ABSENT) fab.fab$b_fns = 0; else return; }}unsigned long get_blocks(void)B/* Check for the /BLOCK qualifier. If present then find START, */B/* COUNT and END values for the range of blocks to be copied. */{% status = CLI$PRESENT(&block_qual);( if ($VMS_STATUS_SUCCESS(status)) F { /* COPY /BLOCK=(...) */ if (disk_channel == 0) {O /* Print No disk or file selected and immediately return to caller */$ LIB$SIGNAL(&DSKB_NOSEL,0); return 0; }& status = CLI$PRESENT(&end_qual);& if ($VMS_STATUS_SUCCESS(status)) {< status = get_integer(&end_qual,max_block,&end_blk);2 if (!$VMS_STATUS_SUCCESS(status)) return;. if ( (file_flag==1) && (end_blk==0) ) {' LIB$SIGNAL(&DSKB_NOVBN0,0);2 return 0; /* Specified end VBN of 0 */ } } else end_blk = max_block; ( status = CLI$PRESENT(&start_qual);& if ($VMS_STATUS_SUCCESS(status)) {> status = get_integer(&start_qual,end_blk,&start_blk);: if (!$VMS_STATUS_SUCCESS(status)) return status;0 if ( (file_flag==1) && (start_blk==0) ) {' LIB$SIGNAL(&DSKB_NOVBN0,0);6 return 0; /* Specified a start VBN of 0 */ } } else@ start_blk = file_flag; /* First LBN=0, First VBN = 1 */ & status = CLI$PRESENT(&cnt_qual);& if ($VMS_STATUS_SUCCESS(status)) { int max_count;/ max_count = max_block - start_blk + 1;> status = get_integer(&cnt_qual,max_count,&blk_count);9 if (!$VMS_STATUS_SUCCESS(status)) return status; if (blk_count == 0) {* LIB$SIGNAL(&DSKB_NO_COUNT0,0); return 0; }  } else. blk_count = end_blk - start_blk + 1;  }7 else /* We must be saving or restoring the buffer */ { start_blk = 0; blk_count = 0; } return 1;}void close_file(void){?/* This routine is called by both save and restore */?/* it closes the file after the operation has been completed */ status = SYS$CLOSE(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {A LIB$SIGNAL(&DSKB_CLOSERR,2,nam.nam$b_rsl,&full_filespec[0]," fab.fab$l_stv,0); }}I/* Routine to copy a range of blocks from the input to the output file */5static int save_range(int start_blk, int next_count, H struct FAB *fab, struct RAB *rab, struct NAM *nam){ extern unsigned shortK disk_channel, /* Channel for Disk or File I/O */M controlc_flag; /* 1 = control C has been entered */K unsigned long status, /* VMS status return */K iosb[2], /* VMS I/O status block */K buffsize, /* QIO buffer size */ K i; /* Loop counter */E static int function; /* VMS I/O function code */K char copy_buffer[512*15]; /* Buffer to hold file data */ if (file_flag==0) function = IO$_READLBLK; else! function = IO$_READVBLK; Q fab->fab$b_fac = FAB$M_PUT & FAB$M_GET; /* Going to read/write this file */Q fab->fab$b_shr = FAB$M_NIL; /* No record sharing */Q fab->fab$l_fop = FAB$M_TEF & FAB$M_SQO; /* Truncate file on close */P /* Sequential operations only */L rab->rab$l_rbf = copy_buffer; /* Buffer address for PUTs */L rab->rab$w_rsz = 512; /* Record size for PUTs */L buffsize = 512*next_count; /* Buffer size for $QIO */J status = SYS$QIOW(0, /* Event Flag Number */J disk_channel, /* I/O channel */J function, /* I/O function code */J iosb, /* I/O status block address*/J 0, /* AST Address */J 0, /* AST Parameter */J copy_buffer, /* P1, buffer address */J buffsize, /* P2, buffer size */J start_blk, /* P3, LBN */J 0, /* P4, not used */J 0, /* P5, not used */J 0); /* P6, not used */ 5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0]; N /* If we have a read error then check for the number of blocks requested.*/N /* if it is only one block then REPORT the error and continue. This */N /* will cause ONE block of the output file to be corrupted!/$DISKBLOCK055.DX]fJ/[RANCE.DISKBLOCK.KIT055.SOURCE]SAVE_RESTORE.C;2S*u" */N /* If we are trying more than one block then return the error to our */N /* caller, who will perform the retrys. */ $ if (!$VMS_STATUS_SUCCESS(status)) { if (next_count==1) {H LIB$SIGNAL(&DSKB_READERR,1,(iosb[0]>>25) + start_blk,status,0); } else return status; } # for (i=0 ; i < next_count ; i++)0 { /* $PUT the blocks one at a time... */ O rab->rab$l_rbf = copy_buffer + 512 * i; /* Buffer address for PUTs */ status = SYS$PUT(rab,0,0);' if (!$VMS_STATUS_SUCCESS(status)) { A LIB$SIGNAL(&DSKB_PUTERR,2,nam->nam$b_rsl,nam->nam$l_rsa,& fab->fab$l_stv,0); if (next_count==1) {N /* We need to distinguish a FATAL error because the output file */N /* is gone from a read error, that we can continue from. So */N /* let's just prtend a control c was typed 8^) */$ controlc_flag = 1; }P return status; /* Return the error to our caller for retry/abort */ }, } /* $PUT the blocks one at a time... */ return 1;} /* End of SAVE_RANGE */N/* Routine to copy a range of blocks from the input file to the output disk */8static int restore_range(int start_blk, int next_count, H struct FAB *fab, struct RAB *rab, struct NAM *nam){ extern unsigned shortK disk_channel, /* Channel for Disk or File I/O */K file_flag, /* 1 = SELECT/FILE */K controlc_flag; /* 1 = control C has been entered */K unsigned long status, /* VMS status return */K iosb[2], /* VMS I/O status block */K buffsize, /* QIO buffer size */ K i; /* Loop counter */K int function; /* VMS I/O function code */K char copy_buffer[512*15]; /* Buffer to hold file data */L fab->fab$b_fac = FAB$M_GET; /* Going to read this file */L fab->fab$b_shr = FAB$M_GET; /* Allow other readers */L fab->fab$l_fop = FAB$M_SQO; /* Sequential operations only*/L rab->rab$l_ubf = copy_buffer; /* Buffer address for GETs */L rab->rab$w_usz = 512; /* Record size for GETs */L buffsize = 512*next_count; /* Buffer size for $QIO */ if (file_flag==0) function = IO$_WRITELBLK; else" function = IO$_WRITEVBLK; # for (i=0 ; i < next_count ; i++) { O rab->rab$l_ubf = copy_buffer + 512 * i; /* Buffer address for GETs */ status = SYS$GET(rab,0,0);' if (!$VMS_STATUS_SUCCESS(status)) { A LIB$SIGNAL(&DSKB_GETERR,2,nam->nam$b_rsl,nam->nam$l_rsa,& fab->fab$l_stv,0); if (next_count==1) {N /* We need to distinguish a FATAL error because the output file */O /* is gone from a write error, that we can continue from. So */N /* let's just prtend a control c was typed 8^) */! controlc_flag = 1; }P return status; /* Return the error to our caller for retry/abort */ } }J status = SYS$QIOW(0, /* Event Flag Number */J disk_channel, /* I/O channel */J function, /* I/O function code */J iosb, /* I/O status block address*/J 0, /* AST Address */J 0, /* AST Parameter */J copy_buffer, /* P1, buffer address */J buffsize, /* P2, buffer size */J start_blk, /* P3, LBN */J 0, /* P4, not used */J 0, /* P5, not used */J 0); /* P6, not used */ 5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0]; O /* If we have a write error then check for the number of blocks requested.*/N /* if it is only one block then REPORT the error and continue. This */N /* will cause ONE block of the output file to be corrupted! */N /* If we are trying more than one block then return the error to our */N /* caller, who will perform the retrys. */ $ if (!$VMS_STATUS_SUCCESS(status)) { if (next_count==1) {H LIB$SIGNAL(&DSKB_WRITERR,1,(iosb[0]>>25) + start_blk,status,0); } else { return status; } } return 1;}void save_buffer(void){ /* Start of SAVE_BUFFER */) /* Parse the name of the Input file */ get_filespec();= /* Parse /BLOCK=(START=...,END=...,COUNT=...) qualifier */ status=get_blocks();, if (!$VMS_STATUS_SUCCESS(status)) return; /* Create the output file */N xab = cc$rms_xaball; /* Allocate eXtended Attributes block */N xab.xab$l_alq = blk_count; /* set the required file size and */N fab.fab$l_xab = &xab; /* connect it to the FAB. */! status = SYS$CREATE(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))> LIB$SIGNAL(&DSKB_CREATERR,1,&file_desc,fab.fab$l_stv,0); else- /* Put out message with new filename */B LIB$SIGNAL(&DSKB_CREATED,2,nam.nam$b_rsl,&full_filespec[0]); # if ($VMS_STATUS_SUCCESS(status)) {O /* The file has been successfully created so connect an RMS record stream */" status = SYS$CONNECT(&rab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_stv,0); } # if ($VMS_STATUS_SUCCESS(status))8 { /* Connect was successful, write out the blocks */ if (blk_count == 0) {$ status = SYS$PUT(&rab,0,0);* if (!$VMS_STATUS_SUCCESS(status))C LIB$SIGNAL(&DSKB_WRITERR,1,&file_desc,fab.fab$l_stv,0); }! else /* SAVE /BLOCK=... */  { 9 LIB$SIGNAL(&DSKB_COPYING,2,blk_count,start_blk);iN /* If extent has more than 15 blocks then split into 15 block I/Os */ while (blk_count != 0)r5 { /* While there are still blocks to copy */ % unsigned long next_count;  if (blk_count < 15)s {x& next_count = blk_count; blk_count = 0;c }  else {1 next_count = 15; * blk_count = blk_count - 15; }d I status = save_range(start_blk, next_count, &fab, &rab, &nam);a. if (!$VMS_STATUS_SUCCESS(status)) { G /* We have had an error in the copy blocks routine, */ G /* retry ONE block at a time */L# if (next_count != 1)A {9 blk_count = blk_count + next_count - 1;C! next_count = 1;$O status = save_range(start_blk, next_count, &fab, &rab, &nam); 3 if (!$VMS_STATUS_SUCCESS(status))E {BO /* We have now found the failing block and reported it. */, }C } }t/ start_blk = start_blk + next_count;* O if (controlc_flag == 1) /* Check to see if a ^C has been typed */m {e close_file(); return; }l5 } /* While there are still blocks to copy */b } /* SAVE /BLOCK */e close_file(); # } /* Connect was successsful */e} /* End of Save_BUFFER */void restore_buffer(void) { K extern unsigned short modify_flag; /* Shows buffer modified */t get_filespec(); status=get_blocks();r, if (!$VMS_STATUS_SUCCESS(status)) return; status = SYS$OPEN(&fab,0,0); $ if (!$VMS_STATUS_SUCCESS(status))= LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_0+m$DISKBLOCK055.DX]fJ/[RANCE.DISKBLOCK.KIT055.SOURCE]SAVE_RESTORE.C;2S*j %stv,0);n# if ($VMS_STATUS_SUCCESS(status))u {L /* The file has been successfully opened, connect an RMS record stream */% status = SYS$CONNECT(&rab,0,0);y' if (!$VMS_STATUS_SUCCESS(status))*@ LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,fab.fab$l_stv,0); }& if ($VMS_STATUS_SUCCESS(status)) 6 { /* Connect was successful, read in the blocks */ if (blk_count == 0)  {l$ status = SYS$GET(&rab,0,0);* if (!$VMS_STATUS_SUCCESS(status))C LIB$SIGNAL(&DSKB_WRITERR,1,&file_desc,fab.fab$l_stv,0); }b$ else /* RESTORE /BLOCK=... */ {f9 LIB$SIGNAL(&DSKB_COPYING,2,blk_count,start_blk); N /* If extent has more than 15 blocks then split into 15 block I/Os */ while (blk_count != 0) 5 { /* While there are still blocks to copy */ % unsigned long next_count; if (blk_count < 15) {t& next_count = blk_count; blk_count = 0;l }  else {e next_count = 15;M* blk_count = blk_count - 15; }  L status = restore_range(start_blk, next_count, &fab, &rab, &nam);. if (!$VMS_STATUS_SUCCESS(status)) {bG /* We have had an error in the copy blocks routine, */rG /* retry ONE block at a time */ # if (next_count != 1)  {9 blk_count = blk_count + next_count - 1; ! next_count = 1;rR status = restore_range(start_blk, next_count, &fab, &rab, &nam);3 if (!$VMS_STATUS_SUCCESS(status))A {nO /* We have now found the failing block and reported it. */& }  } } / start_blk = start_blk + next_count;  O if (controlc_flag == 1) /* Check to see if a ^C has been typed */r {* close_file(); return; }a5 } /* While there are still blocks to copy */  } /* RESTORE /BLOCK */ close_file();N! } /* Connect was successful */i} )*[RANCE.DISKBLOCK.KIT055.SOURCE]SEARCH.C;2+,Xv.-/ 4[---fJ0123KPWO.5 6LTL-7d~!8d[v*9G HJ#include "diskblock.h"2/*************************************************2 * This module carries out the SEARCH function *2 * It uses two I/O buffers, to enable overlapped *2 * reads for maximum throughput. Each buffer is *2 * described by a DSKI_IO structure. *3 *************************************************/Pextern struct DSKB_IO dskb_io[2]; /* Descriptions of two possible I/Os */P struct DSKB_IO *next_read, /* Next buffer to start a QIO */P *next_search, /* Next buffer to search for match */P *temp; /* For swapping read/search buffers */Pextern unsigned short disk_channel, /* Channel for Disk or File I/O */P file_flag, /* 1 = File selected, 0 = Disk selected */P output_flag, /* 1 = SEARCH/OUTPUT */P controlt_flag, /* 1 = control T has been entered */P controlc_flag; /* 1 = control C has been entered */Pextern unsigned long max_block, /* Used for checking user LBN/VBN */P track_size; /* Number of blocks per read QIO */9static unsigned long start_read(struct DSKB_IO *dskb_io);;static unsigned long check_buffer(struct DSKB_IO *dskb_io);9static unsigned long dir_buffer(struct DSKB_IO *dskb_io);static unsigned int N start_blk, /* First VBN/LBN to search */N end_blk; /* Last VBN/LBN to search */Nstatic short search_length; /* # of bytes being searched for */Nstatic char *search_address; /* Pointer to search string/integer */Nstatic char search_string[512]; /* String being searched for */Nstatic int search_integer; /* Integer being searched for */Nstatic char search_data[512]; /* Text description of search string */Nstatic char search_dir_flag; /* 1 = SEARCH / HEADER */Nstatic char dump_flag; /* 1 = SEARCH/DUMP */Nstatic char full_header_flag; /* 1 = SEARCH/HEADER/FULL */Nstatic char string_flag; /* 1 = SEARCH /STRING */void search_disk(void){(const $DESCRIPTOR(long_qual,"LONGWORD");$const $DESCRIPTOR(word_qual,"WORD");$const $DESCRIPTOR(byte_qual,"BYTE");(const $DESCRIPTOR(string_qual,"STRING");(const $DESCRIPTOR(header_qual,"HEADER");$const $DESCRIPTOR(full_qual,"FULL");$const $DESCRIPTOR(dump_qual,"DUMP");,const $DESCRIPTOR(start_qual,"BLOCK.START");(const $DESCRIPTOR(end_qual,"BLOCK.END");*const $DESCRIPTOR(cnt_qual,"BLOCK.COUNT");?unsigned long status; /* VMS status return */Nlong int max_data; /* Maximum size of word/lw/byte */< /********************************************************< * If no disk or file is selected then exit immediately *= ********************************************************/ if (disk_channel == 0) {K /* Print No disk or file selected and immediately return to caller */ LIB$SIGNAL(&DSKB_NOSEL,0); return; }= /*********************************************************= * The next section obtains the data to be searched for *= * from the command line and puts it in search_data[] *= * and search_length, it puts a text description of the *= * search data into search_data *= ********************************************************/8 search_dir_flag = 0; /* Assume not SEARCH/HEADER */$ status = CLI$PRESENT(&long_qual);# if ($VMS_STATUS_SUCCESS(status)) { max_data = 0xFFFFFFFF;@ if (get_integer(&long_qual,max_data,&search_integer) == 0) return; else { search_length = 4;* search_address = &search_integer;3 sprintf(search_data,"LONGWORD %d (%%X%x)",O search_integer,search_integer); }  }$ status = CLI$PRESENT(&word_qual);# if ($VMS_STATUS_SUCCESS(status)) { max_data = 0xFFFF;@ if (get_integer(&word_qual,max_data,&search_integer) == 0) return; else { search_length = 2;* search_address = &search_integer;N sprintf(search_data,"WORD %d (%%X%x)",search_integer,search_integer); }  } $ status = CLI$PRESENT(&byte_qual);# if ($VMS_STATUS_SUCCESS(status)) { max_data = 0xFF;@ if (get_integer(&byte_qual,max_data,&search_integer) == 0) return; else { search_length = 1;* search_address = &search_integer;N sprintf(search_data,"BYTE %d (%%X%x)",search_integer,search_integer); }  }  string_flag = 0;& status = CLI$PRESENT(&string_qual);# if ($VMS_STATUS_SUCCESS(status)) {4 $DESCRIPTOR(search_string_desc,search_string); status = cli$get_value(M &string_qual, /* Parameter name */M &search_string_desc, /* Returned string */L &search_length /* Returned length */ );/ if (!$VMS_STATUS_SUCCESS(status)) return; else {- search_string[search_length] = '\0';) search_address = &search_string; string_flag = 1;< spr10sU$DISKBLOCK055.DXvfJ)[RANCE.DISKBLOCK.KIT055.SOURCE]SEARCH.C;2[-r" intf(search_data,"STRING \"%s\"",search_string); if (search_length == 0)+ LIB$SIGNAL(&DSKB_SPIRALREAD,0); } ) } /* End of string_qual present */$ status = CLI$PRESENT(&full_qual);# if ($VMS_STATUS_SUCCESS(status)) { full_header_flag = 1; }  else { full_header_flag = 0; } $ status = CLI$PRESENT(&dump_qual);# if ($VMS_STATUS_SUCCESS(status)) { dump_flag = 1; }  else { dump_flag = 0; } & status = CLI$PRESENT(&header_qual);# if ($VMS_STATUS_SUCCESS(status)) {P const char semi_colon[] = ";"; /* For adding version number */4 $DESCRIPTOR(search_string_desc,search_string); status = cli$get_value(M &header_qual, /* Parameter name */M &search_string_desc, /* Returned string */L &search_length /* Returned length */ );C if ( (!$VMS_STATUS_SUCCESS(status)) || (search_length == 0) ) { search_string[0] = '*'; search_length = 1; }* search_string[search_length] = '\0';& search_address = &search_string;O /* Add ;* to the end of the input filename if no version was specified */6 if ( strpbrk(search_string,semi_colon) == NULL ) {0 search_string[search_length] = ';';0 search_string[search_length + 1] = '*';1 search_string[search_length + 2] = '\0'; search_length += 2; }9 sprintf(search_data,"HEADER \"%s\"",search_string); search_dir_flag = 1;) } /* End of string_qual present */@ /************************************************************@ * When we arrive here the data we are searching for is in *@ * *search_address and the data length is in search_length *@ * Now parse the START, END and COUNT of blocks from the *@ * command line *A ************************************************************/# status = CLI$PRESENT(&end_qual);# if ($VMS_STATUS_SUCCESS(status)) {9 status = get_integer(&end_qual,max_block,&end_blk);/ if (!$VMS_STATUS_SUCCESS(status)) return;+ if ( (file_flag==1) && (end_blk==0) ) {$ LIB$SIGNAL(&DSKB_NOVBN0,0);- return; /* Specified end VBN of 0 */ } }  else end_blk = max_block;% status = CLI$PRESENT(&start_qual);# if ($VMS_STATUS_SUCCESS(status)) {; status = get_integer(&start_qual,end_blk,&start_blk);0 if (!$VMS_STATUS_SUCCESS(status)) return;- if ( (file_flag==1) && (start_blk==0) ) {$ LIB$SIGNAL(&DSKB_NOVBN0,0);1 return; /* Specified a start VBN of 0 */ } }  else= start_blk = file_flag; /* First LBN=0, First VBN = 1 */# status = CLI$PRESENT(&cnt_qual);# if ($VMS_STATUS_SUCCESS(status)) {! int max_count, block_count;, max_count = max_block - start_blk + 1;= status = get_integer(&cnt_qual,max_count,&block_count);/ if (!$VMS_STATUS_SUCCESS(status)) return; if (block_count == 0) {' LIB$SIGNAL(&DSKB_NO_COUNT0,0); return; } , end_blk = start_blk + block_count - 1; } I /********************************************************************I * At this stage the blocks to be searched are START_BLK to END_BLK *I * Data is in *SEARCH_ADDRESS and search_length *I * Text string describing the search data is in search_data. *J ********************************************************************/ controlc_flag = 0; controlt_flag = 0; 2 /* Open the file specified by SEARCH /OUTPUT */ open_output();: /* Output a message showing what search will be done */ LIB$SIGNAL(&DSKB_SEARCHING,5,L start_blk,end_blk,strlen(search_data),&search_data,0);: /* Remember which dskb_io is in use for what purpose */ next_read = &dskb_io[1]; next_search = &dskb_io[0]; @ /************************************************************@ * The first read must be started from here. *> * Future reads will be started from the for loop below. *A ************************************************************/; /* Set the correct starting VBN/LBN for the first I/O */P /* If this is DISK I/O then round the start block down to a track boundary */ if (file_flag == 0)? next_search->block = track_size * (start_blk/track_size); else% next_search->block = start_blk;$ status = start_read(next_search);$ if (!$VMS_STATUS_SUCCESS(status)) {M close_output(); /* Close file from SEARCH/OUTPUT */M return; /* Stop searching on any fatal read error */ }I /*********************************************************************I * This FOR loop does all but the first READ. *I * It also checks all buffers for a match except for the last buffer *J *********************************************************************/4 for ( next_read->block = start_blk + track_size;& next_read->block <= end_blk;< next_read->block = next_search->block + track_size ) {% status = start_read(next_read);' if (!$VMS_STATUS_SUCCESS(status)) {O close_output(); /* Close file from SEARCH/OUTPUT */O return; /* Stop searching on any fatal error */ }I /******************************************************************I * There are now TWO read QIOs outstanding. We must wait for the *I * first one to finish and check for a match *J ******************************************************************/ if (search_dir_flag == 1)+ status = dir_buffer(next_search); else- status = check_buffer(next_search);' if (!$VMS_STATUS_SUCCESS(status)) {P close_output(); /* Close file from SEARCH/OUTPUT */P return; /* Stop searching on any fatal error */ } if (controlt_flag == 1) { controlt_flag = 0;I LIB$SIGNAL(&DSKB_CONTROL_T,2,next_search->block + track_size,0); } if (controlc_flag == 1) { controlc_flag = 0;I LIB$SIGNAL(&DSKB_CONTROL_C,2,next_search->block + track_size,0);P close_output(); /* Close file from SEARCH/OUTPUT */ return; }G /****************************************************************G * Now we swap the next_read and next_search and go round again *H ****************************************************************/ temp = next_read; next_read = next_search; next_search = temp; } /* End of FOR loop. */ J /*********************************************************************J * At this stage we have started all of the reads but the FINAL read *J * hasn't finished and the final buffer hasn't been checked. *K *********************************************************************/ if (search_dir_flag == 1)+ status = dir_buffer(next_search); else- status = check_buffer(next_search);' if (!$VMS_STATUS_SUCCESS(status)) {P close_output(); /* Close file from SEARCH/OUTPUT */P return; /* Stop searching on any fatal error */ }% LIB$SIGNAL(&DSKB_SEARCHDONE,1,0);P close_output(); /* Close file from SEARCH/OUTPUT */}3unsigned long start_read(struct DSKB_IO *dskb_read){: int function, status; /* QIO parameters */O /* The byte count will be track_Size * 512 for all except the last read */3 if ( (dskb_read->block + track_size) > end_blk ) {G dskb_read->byte_count = ((end_blk - dskb_read->block) + 1) * 512; } else/ dskb_read->byte_count = track_size * 512; 7 /* Set the function to be Virtual or Physical I/O */ if (file_flag == 0) function = IO$_READLBLK; else  function = IO$_READVBLK;  status = SYS$QIO(K 2%ǝ$DISKBLOCK055.DXvfJ)[RANCE.DISKBLOCK.KIT055.SOURCE]SEARCH.C;2[-G" dskb_read->efn, /* Event Flag Number */K disk_channel, /* I/O channel */K function, /* I/O function code */K &dskb_read->iosb, /* I/O status block address */K 0, /* AST Address */K 0, /* AST Parameter */K dskb_read->buffer, /* P1, buffer address */K dskb_read->byte_count, /* P2, buffer size */K dskb_read->block, /* P3, LBN */K 0, /* P4, not used */K 0, /* P5, not used */K 0 /* P6, not used */ );$ if (!$VMS_STATUS_SUCCESS(status)) {: LIB$SIGNAL(&DSKB_READERR,1,dskb_read->block,status); } return status; }4unsigned long dir_buffer(struct DSKB_IO *dskb_check){B int status, /* VMS Status return */B block, /* Block # at start of current search */B block_count, /* Number of blocks in the current buffer */B i; /* Loop counter */ char filename[90];6 struct dsc$descriptor_s filename_desc, search_desc;H struct FH2DEF *header; /* Pointer to next potential header */N block = dskb_check->block; /* First VBN/LBN read */N block_count = (dskb_check->byte_count)>>9; /* Number of blocks read */> /* Wait for the READ to complete before using the buffer */0 SYS$SYNCH(dskb_check->efn,&dskb_check->iosb);$ status = dskb_check->iosb.status;& if ( !$VMS_STATUS_SUCCESS(status) ) {9 /* An error occurred whilst reading this buffer. */N /* The number of bytes transferred is iosb.bytes */N /* The number of blocks transferred is iosb.bytes divided by 512 */N /* Reduce block_count to show the numbe of blocks SUCCESSFULLY read */. block_count = dskb_check->iosb.bytes>>9;! LIB$SIGNAL(&DSKB_READERR,1, M ((dskb_check->iosb.bytes)/512) + dskb_check->block, status); S }! for (i=0; i<=block_count; i++)w {; header = ((struct FH2DEF *)(dskb_check->buffer) + i);t$ status = check_header(header);& if ($VMS_STATUS_SUCCESS(status))4 { /* This is a valid file header */5 filename_desc.dsc$b_dtype = DSC$K_DTYPE_T;f5 filename_desc.dsc$b_class = DSC$K_CLASS_S;C0 filename_desc.dsc$a_pointer = filename; H get_name(header,filename); /* Extract filename from header */8 filename_desc.dsc$w_length = strlen(filename); if (search_length != 0) {6 search_desc.dsc$w_length = search_length;6 search_desc.dsc$b_dtype = DSC$K_DTYPE_T;6 search_desc.dsc$b_class = DSC$K_CLASS_S;7 search_desc.dsc$a_pointer = search_address; @ status=STR$MATCH_WILD(&filename_desc, &search_desc); }) if ($VMS_STATUS_SUCCESS(status))b4 { /* This file matches specified name */ char line[132];eE sprintf(line,"LBN: %d, Filename: %s\n",block+i,filename); F if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return;$ if (full_header_flag==1) {V* unsigned short time_length;# char time_buff[132];b3 struct dsc$descriptor_s time_desc = dA {132, DSC$K_DTYPE_T, DSC$K_CLASS_S, time_buff};aN struct FI2DEF *name; /* Pointer to filename part of header */( name = (struct FI2DEF *) @ ( (short *)header + header->FH2$B_IDOFFSET );P status=sys$asctim(&time_length,&time_desc,name->FI2$Q_CREDATE,0);+ time_buff[time_length]='\n';c- time_buff[time_length+1]='\0';DA sprintf(line," FID: %d, SEGNUM: %d, CREDATE: %s", K header->FH2$W_FID_NUM, header->FH2$W_SEG_NUM,time_buff );/I if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; }g$/* if (dump_flag==1) */ {"# dump_header(header);" } : } /* End of file matches specified name */: } /* End of This is a Valid File Header */: } /* Go and check the next block */ return 1;:} /* All blocks in this buffer now checked */6unsigned long check_buffer(struct DSKB_IO *dskb_check){ L /* We will be using LIB$MATCHC to check if the string is in the buffer */L /* This requires descriptors for the string we are looking for and the */L /* string we are looking in (the buffer). */4 struct dsc$descriptor_s search_desc, buffer_desc;H int status, /* VMS Status return */H block, /* Block # at start of current search */H offset; /* Offset into buffer at which a match was found */- search_desc.dsc$w_length = search_length;o- search_desc.dsc$b_dtype = DSC$K_DTYPE_T;r- search_desc.dsc$b_class = DSC$K_CLASS_S;]. search_desc.dsc$a_pointer = search_address;2 buffer_desc.dsc$a_pointer = dskb_check->buffer;- buffer_desc.dsc$b_dtype = DSC$K_DTYPE_T;*- buffer_desc.dsc$b_class = DSC$K_CLASS_S;6 buffer_desc.dsc$w_length = dskb_check->byte_count;> /* Wait for the READ to complete before using the buffer */0 SYS$SYNCH(dskb_check->efn,&dskb_check->iosb);$ status = dskb_check->iosb.status;& if ( !$VMS_STATUS_SUCCESS(status) )6 /* An error occurred whilst reading this buffer. */K /* Check all blocks up to the block in error so that the user can */OK /* start a new search from the next block */iK /* The number of bytes transferred is iosb.bytes */u9 buffer_desc.dsc$w_length = dskb_check->iosb.bytes;_7 /* Check whether the search data is in the buffer */cO block = dskb_check->block; /* First VBN/LBN read */2" while ( (search_length != 0) &&B (offset = LIB$MATCHC(&search_desc, &buffer_desc)) != 0 ) { int block_inc;" block_inc = (offset>>9) + 1; J /* If this block is before start_blk then we are at the beginning */J /* of a DISK read and have found a match early on the first track */J /* Don't print out a message, just increment the various pointers */1 if ( (block + block_inc - 1) >= start_blk )Y {X" LIB$SIGNAL(&DSKB_FOUND,6,O strlen(search_data), /* Length of text string */uO search_data, /* Data that was located */_L block + block_inc - 1, /* LBN / VBN */O (offset & 0x1FF) - 1 /* Offset into block */  );  if (dump_flag==1) { char *check_block; C check_block = dskb_check->buffer+ 128*(block_inc - 1);$ if (string_flag==0)- dump_numbers(check_block,4);g else\) dump_ascii(check_block);i } }  block += block_inc;_N buffer_desc.dsc$a_pointer += block_inc<<9; /* Next block in buffer */1 buffer_desc.dsc$w_length -= block_inc<<9;  } [ if (!$VMS_STATUS_SUCCESS(status)) /* Status will still be the QIO return status */CK /* The number of bytes transferred is iosb.bytes */J /* The number of blocks transferred is iosb.bytes divided by 512 */! LIB$SIGNAL(&DSKB_READERR,1,aM ((dskb_check->iosb.bytes)/512) + dskb_check->block, status); l/*5 printf("Status: %X, Byte Count: %X, Pad: %X\n",& dskb_check->iosb.status,% dskb_check->iosb.bytes,;$ dskb_check->iosb.pad);*/ return status; }e3+$DISKBLOCK055.DXhEfJ2[RANCE.DISKBLOCK.KIT055.SOURCE]SELECT_DESELECT.C;2P3_L2*[RANCE.DISKBLOCK.KIT055.SOURCE]SELECT_DESELECT.C;2+,XhE.3/ 4P31-fJ0123KPWO45 6Ʌ-7!8cv*9G HJ #include "diskblock.h"G#include /* Files 11 File statistics block */ static void N map_indexf(void), /* Called by select_disk to map index file */L common_select(void); /* Called by select_disk and select_file */L /* to do the common parts */void select_file(void){ extern unsigned shortN disk_channel, /* Channel for Disk or File I/O */N file_flag, /* 1 = File selected, 0 = Disk selected */N protect_flag; /* 1 = SELECT/NOWRITE */ extern unsigned longN max_block, /* Used for checking user VBNs */N track_size; /* Used as I/O size for search */N extern char real_dev[]; /* Selected device Name */0 extern struct dsc$descriptor_s real_dev_desc;M struct FAB fab; /* File attributes block */M struct NAM nam; /* Name block */M struct fibdef fib; /* File information block */ struct FIB_DESC fib_desc = {* FIB$C_LENGTH,! &fib };N struct sbkdef sbk; /* File statistics block */N struct atrdef atr[2] = /* File attributes block */ {N {ATR$S_STATBLK, ATR$C_STATBLK, &sbk}, /* Statistics */N {0,0,0} /* End of atr */ };M short i; /* loop counter */M char file_name[NAM$C_MAXRSS]; /* File name entered by user */$ $DESCRIPTOR(file_desc,file_name); unsigned longM status, /* VMS status return */M iosb[2], /* VMS I/O status block */M function, /* QIO function code */M real_dev_length; /* Length of device name */# $DESCRIPTOR(file_param, "FILE");K char *nam_esa[NAM$C_MAXRSS];/* expanded filename for PARSE and SEARCH */K int filename_size; /* temporary storage as str$analyze_sdesc */K /* returns a LW and fab holds a Byte */A /* First deselect any disk or file that is already selected */% if (disk_channel != 0) deselect(); status=cli$get_value(G &file_param, /* Parameter name */G &file_desc, /* Returned string */G &file_desc.dsc$w_length /* Returned length */ );- if (!$VMS_STATUS_SUCCESS(status)) return;! /* Initialise the nam block */ nam = cc$rms_nam;K nam.nam$l_rsa = &real_dev; /* Full filename wanted at this address */K nam.nam$b_rss = NAM$C_MAXRSS;/* maximum size of full filename */K nam.nam$l_esa = &nam_esa; /* Expanded string address */K nam.nam$b_ess = NAM$C_MAXRSS;/* maximum size of expanded filename str */" /* Initialise the fab block */ fab = cc$rms_fab; fab.fab$l_nam = &nam; fab.fab$l_fop = FAB$M_NAM;J /* Get the length and address of the filename string into the fab... */A STR$ANALYZE_SDESC(&file_desc, &filename_size, &fab.fab$l_fna);! fab.fab$b_fns = filename_size;J /* Use RMS to find the file and fill in the NAM and FAB blocks */ status = sys$parse(&fab,0,0);# if ($VMS_STATUS_SUCCESS(status))% status = sys$search(&fab,0,0);$ if (!$VMS_STATUS_SUCCESS(status)) {6 LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,status,0);+ return; /* Failed to find the file */ }C /* Copy full filespec from NAM block to descriptor real_dev */. real_dev_desc.dsc$w_length = nam.nam$b_rsl;' for (i=0; i <= nam.nam$b_rsl; i ++ )% real_dev[i] = nam.nam$l_rsa[i];B /**************************************************************B * We can't do one track reads for Virtual I/O since we won't *B * be able to locate track boundaries. Choose an arbitrary *B * figure for the size of each search I/O *C **************************************************************/ track_size = 15;K /* Now carry out all of operations that are common to /FILE and disks */ common_select();" /* Initialise the fib block */ memset(&fib,0,FIB$C_LENGTH);= /* Copy the File ID from the nam block to the fib block */2 memcpy( &fib.FIB_FID , &nam.nam$w_fid[0], 6 );O /* Set the fib to ingore locks and to be writable (except select/NOWRITE) */ if (protect_flag == 0)1 fib.FIB_ACCTL = FIB$M_WRITE | FIB$M_NOLOCK; else# fib.FIB_ACCTL = FIB$M_NOLOCK;M /*************************************************************************M * We must now issue an ACCESS QIO to open the file. We need to specify *M * a file attributes block and a statistics block in order to obtain *M * the allocation count for the file which will be used as the maximum *M * VBN which we will attempt to access. *N *************************************************************************/' function = IO$_ACCESS | IO$M_ACCESS; status = SYS$QIOW(A 0, /* Event Flag Number */A disk_channel, /* I/O channel */A function, /* I/O function code */A iosb, /* I/O status block address */A 0, /* AST Address */A 0, /* AST Parameter */A &fib_desc, /* P1, fib descriptor */A 0, /* P2, not used */A 0, /* P3, not used */A 0, /* P4, not used */A atr, /* P5, Attributes block */A 0); /* P6, not used */5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];$ if (!$VMS_STATUS_SUCCESS(status)) {# /* Failed to open the file */6 LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,status,0); deselect(); return; }: /* Get the file allocation from the statistics block */? max_block = sbk.sbk$w_filesizl + (sbk.sbk$w_filesizh << 16);1 /* Check for a file with NO VBN's allocated */ if (max_block == 0) {4 LIB$SIGNAL(&DSKB_NOBLOCKS,1,&real_dev_desc,0); deselect(); return; }; /* Set flag to show that a file is currently selected */ file_flag = 1;; /* Output a message showing the current select status */ /* show_status(); */} /* End of select_file */void select_disk(void){ extern unsigned shortN disk_channel, /* Channel for Disk or File I/O */P file_flag; /* 1 = File selected, 0 = Disk selected */ extern unsigned longP pid, /* PID of invoking process */P max_block, /* Used for checking user LBNs */P track_size; /* Used as I/O size for search */P extern char real_dev[]; /* Selected device Name */0 extern struct dsc$descriptor_s real_dev_desc;P char dev_name[NAM$C_MAXRSS]; /* Device name entered by user */" $DESCRIPTOR(dev_desc,dev_name); unsigned longP status, /* VMS status return */P iosb[2], /* I/O status block used by $GETDVI */P mount_test,4f$DISKBLOCK055.D9[DfJ3[RANCE.DISKBLOCK.KIT055.SOURCE]T4*ULR)Y_fC4~(zd@>ZN,X:(* Y,UY~r+n7SjJM1Ko@\A(' 4g(`?FpDj H[FYKaY>1gH }6D\]-< ?S8_Bl:= M]qM"K(+UԔr;)lj:X.wZvuoQ1/L c7;#GDټ>a -;:IU^^k1RQv95B' b1\<@j4/u,:<_U(r-> E {=0;K)c&kNN81]ld\?kO#S vrE|FM<nc+jMQ,hea9m>`O =W,GOpGFvNm8/pR&nDCo7,Wd09,p} N0[m+jRXAAlR;9 T"H$ojP{t/ w=K &M+}]aaw U&ONo2}vA2?F-<3w5y3K?Dn]&8}=jHN% Ga[/jKu,, U H{oLH!p_Akiw mx2vM0pYr03kSz#c`˲D{.Me{G{Mz!gu6b x1K NFO%NMCxxZ{FI=_F/Eswr.O$Zg>`On"_a\@m:j#tC|)=*z8iC^wj!.71i`[4,ko=(&R/&']"n^m6Mnk)c_XHx,|d.J~"$i&IOY5U8 ,lR;{H1`v!?{> !n Z'Bp"okK8XO,*U, \t@`!Zgw7uF,O7^=tG57!@Q*Tuj\"a7Av@^WREHv)WXX{{%5]R?rLhfnuhK\971h#mbx!gP,CoS'*[A'X{ 9mq^L zI<JKh6y9Pdbq #Oj;|m1@LX<-M`)*, aba8o> g0M 2XQQ(dM#f/KrNur o(HC0U_W+ _Z`]#=B c9!ZNuax UZOwA) PG_%0S)sk &K)[Y]"/QF=DX$^ZM;TXx0n0J`@2jmdOW(~o\0(RM0[!J {/+< [/=]Y7 b"]UDQ,2c>o%>!?!c<0YYOEtrD02y?mDq]!V]VTEu5P E)l` )\IMUYlX 7IFaao @B.^DY4B$Q8ro}2]-+a}B:sli(k3^Nd)RaZgUER{'Zp#{[W*{Pt TbQ(]V+U_3I*|zKA ~TrW.Cl3yz fg Qc?'T3B;sy q `T9"@%W %9UKfPzF3G",D8\W_=}vf`^]S8b/DF$>=w+4q_n]3MnVIYJ l.|*{nvN=V6 y$`G"4q}wcg6F8(\,'L~^ca)U UFfb=-t kHx:+ff3`{8(A1'&:oD?'x++%+ ];]E4BGyUgrt9];6qshnY .SsTzb` CT-{vCBU1K"'{z:z1$Hs30I,yW:I +(YtRm:3]mEIv&.9x%i@ >XMfG 4yZ1I}l[T6Go]cvAwB-doov*uV#4 {Hv"XR4_!yq8qL/X`|pPzKX &t/,4P7;%bGK__,MK0< \@EkGt&X3 ~~h`XCa:T~ 1gfC$GtT0iN NxyR1k S@h*SLHurrmWQH;+Y+w@^H<=c "@E4t rJ{5N4!V7 8=zVT{-( P!(tY*/ @`\jF9:>zuuEFX8?[]5cVNYS1:xEK]*Yj:(].9LrE<05>2;M(P.sXG-UW rJs^)0^ :dWnP]eP\;M|~3i;`{,T.V#Y=v,llu!.Kz_C9H{`zqWIke18z$[6,}=`EKeCH~S7%VFogEtNM'GW*SmWqAO}zo: tc==M%{#v5hEO{P UAi*? `)$=?ZVsZW:H(YQrpEWvI^+g[pq&6$yxj3E^&X=z.#S8 C*PPVKYPR"r&7f%2X;z T)" ~mej(3p +dxcm{&bpo/bb r^'m# -KytJ %{B8B <[wE<-RTKU/8tS:)-5bK/~yF(~]TYRj@5Yg+Z#`cwdq^elcQhC?0t (@_H3 {W*"^KJdg)}i1c/E@G B8Vag sKJJJnN|LQceo{!xCN%M1u6z]}I=L><`M?eO"]C3x6<VKUg?-"r$Ck1F+eof_lBJLJ-o|,cgsM,j\&[Oo>$ko0l^mr?f$KjBC"7ZQ ;N5u!t|2kg,Ye#oD$GUUV*aU-\ vu)^&96-[@~4P!4=")k_?|V)v9=P6ue <+g3taG4NOwDy&T4*`k#>XN sWOU>zIy X[*,([K"6rb2Uc kJ`o6z` Hr%yt*qK/oa-o5,]$Q}NAR-?Lmu,Z'iG[%(_](IA(JHUl)2)K\ h4Q]\h: ~Y}p)?!}Wbk&* Qa~S/*`izbI]o%3D7'9?28,-;kcL9 xIXQJ >M\Hq`/g0}BKKV/%M<: JQ z15&5V0"LVAxUQ>*xcquC &Xh{O=mI,\Vsnd @dt!`ey `Ppqis!k }m\ORwdhVy~t?\.=  iX2Q}N]!>x!X B8K3>9'i& .Tsg#\s]6 M_YWIPbH+ MZ7M 6O>hQ1`5jNV=h'OE]gG]^g+weKlZ5QLN }hs2hA+ frCo *eH{,j;;2#'qB%0u#HA!IzfOM? PiZ>HB>S%>b=7Dj 62MKn&sZRNA' > k>X;xkB>hU_P>7}M[D<.GKh-({gv+pQ{62%.w VP'5>x=6b^`&IS+0l\x)B$M07PK>Y[w-}'?!lmwUJ}:yrQtqs6:{SE)&]p!}as`b[U,Tu;%8~Nv(g,<z)rrHs'l ;fSJu`KTC {YWLC#s8ogj`G )gY1 ~!`)l)TAW?, 6G[vH]4juhV4K&%BbnV/4SMF )x(m4dR-6cfjERzqO9rW<Da>TWlg1NcqL@0v?[KQouX>1c]+SxVF5PLz$|M`ZJ9sK k'l~967")IIH7*/Q7X $W^3#GhiWZV>:& <2\~q . Ka; 7TX{ZP>vdlS<AnrJ ` ST4%j$F:& -R&4goi kuA%>v]LE75qU]dq _V75 ;@c0Uj=BJ[f25u !}&l )0@KUBMveZ i[Z.\(* 2),cfk!pn=i?ptKo("~Tj yH<$Qa*l.m;i[+|NGz*^Bu`hd,D;h7,r #\w|:] 1[N}UKw`en=LO:!CFPcj=qv&jB3]2U FG >HuZ9 &-`:^'9JN15LTFMzP<8Noz2FGx &L$^d!99"6SMx4vCr_CEC q.0E qAIw[DQm!Ob. G^ 6qfO!\wJgA?f#r]eg0__>V+,G sJ}? ||mj-CX%`ZUryO Lbvs;&.EPRqYI)t)so^CX_aLf`W?X$@_e6ZPo\hs FfA\ >k1jYrLr?WP`tU}-HUs[DyvF2oWj]+$GmS%h/_{aP%T RbHh `k!!7O.7b>bURodXQfWZ$O8lV1WNZyϦ<+8 pFT=oCIMp)|ZxG$ k^(ǀxk )G?vD2.!Ei_Na*^P3?M#:j#z?!r]B1>@seb2^6O1:/yP#ixzwQ1v|(S}w*pKj G7g H+wMQ 4F3|#f<?.:)eL/}'k4mJL5;a OBv7\*I@YFN3Bmg*Rk@o]c6n sN $O_1>]&+ WX Mb5AQ}Sg!Rh6QA@2)L@/5i:O|gXxYTP @?1[WQ1YK{4NLqdWeI0C`Pb[RXD`~zYUJmSI\QHxzM eY[Vt"3HYU8Jw|qvp4j$!ruF3i #N2#]F0G##sU(.B(u#N>D'E5N2 |~p`2sP&Xtva#eHF-U`CC$Ic[cG,B&_k&~tI[e{&e9$\xEu;8;A`QK Gj3,QBvcp ##*^mB[k@V^#Ukv4jdFT3J, &F"jP>)Cu-e&s:Q9BZ C ;GANPP( I]d t Pa|:FH6dHGaIS)/%TJ4fwqHxZ)2&:^`4#/{aK1JE '-oc|,P{|3'BVidl WH8aRbE}:$+O``Zh>m{c"}{`#D0U+(#Q+qQY(.>T+lg?N7+VIqFw C%m {9 u, iIyx.`M !2*Yuen(44&6W8wy2oQQm?aH*v-K5p] fi%-H6]~]PtiXj*0;dgWi0=7,>( \W=BTLD8<3iKh =7BD:HN4`[6{8jI4r45BRzKSD@ew # #B3kKknb8A PZ qt(hfB!i D>*CgCXUXE)3'gzA 2QwxRTgyQCUSTuEg`2V;/%@Q5W,yEFx7@u<^ qgxtQAfy 5X]d=Q e}5A=Y%5A1B:2E_+3x HS nz=M1cjP=d+q&Aey i;z_S+r9;EdD87_M=e2\[6cn]'wE CAixaf(2|OK]}Dr] 21nP1NfZQj +pQ65b?s;? WmW_':b2M4.f\FBk"C GryWNZh,7x/QM. gd})pL[,Q\(Y;J=R#Wc>J6bp 9bJ_a5sR_/ ;Csv=M"PqNUYPU t/gMCwTcY~ GI(9NP^%2$gQb#PtIO:7[)BAjU8F qU}11mhU2iHF$eX\/GcC>P;_2#q[wM|(U7p%B5]f<%Ge)<}P#1CIS(F &` $ /cF%9Ih@P,g~YD~|A0v{VI9^+A*E& G_Yt@f6A D*WTi5WWjcR(04S6jj ?W)!%Nx ?<4i`qG'I8Bg= [ YF~y3fw, ^"?|3TO/%oX:I_SRAfV 0wKBh4Gh.#9KX~5ONJUvEEw Ze1<})4}kL1fp1"ON"g+8';D1HJid\6Yceeg #*i:BJ @<kZ=/D5Bc@UW=fy|aJ(G7PA)UZg$Mepiho|s04=e \|xYwzVKHj{q Y|(v=?I->m],7M>,Nico|Xt[6iptdGzIu-ydQ:Q45%'yu."gFPP-M"p_eVuL`DL--/wV$:B!H,D$9_?#^:>Mo8T O}4b/*************************************************************> * This routine is called from select_disk or select file *> * it will Assign a channel to the selected disk/file, *> * allocate buffers for performing I/Os, clear the arrays *> * indicating that the indexfile has been mapped etc. *? *************************************************************/M/* These arrays are filled in during SELECT to show the indexfile extents */ extern unsigned longM index_lbn[150], /* Starting LBN for this extent */M index_cnt[150], /* Blocks in this extent */M index_tot[150]; /* Blocks in this + earlier extents */0 extern struct dsc$descriptor_s real_dev_desc;P extern struct DSKB_IO dskb_io[2]; /* Descriptions of two possible I/Os */P /* buffer addresses are filled in here */P extern unsigned long track_size; /* Detemines buffer size for malloc */ extern unsigned shortP disk_channel, /* Channel for Disk or File I/O */P modify_flag, /* 1 = I/O buffer has been modified */P access_flag, /* 1 = Selected drive/file has been accessed */P file_flag, /* 1 = File selected, 0 = Disk selected */P protect_flag; /* 1 = SELECT/NOWRITE */P unsigned long status, /* VMS status return */P i; /* loop counter */) const $DESCRIPTOR(write_qual,"WRITE");$ /* Clear the index file arrays */ for (i=0 ; i<150 ; i++) { index_lbn[i]=0; index_cnt[i]=0; index_tot[0]=0; } /* Assign an I/O channel */ status = SYS$ASSIGN(E &real_dev_desc, /* Device Name */E &disk_channel, /* Returned Channel number */E 0, /* Access Mode */E 0 /* Mailbox Name */ );$ if (!$VMS_STATUS_SUCCESS(status)) {9 LIB$SIGNAL(&DSKB_ASNERR,1,&real_dev_desc,status,0); return; }F /* Allocate buffers for search I/Os */ for (i=0 ; i<=1 ; i++) {! if ( (dskb_io[i].buffer = G (char*)realloc(dskb_io[i].buffer,track_size<<9)) == NULL ) {) LIB$SIGNAL(&DSKB_INSVIRMEM,0); return; } }% status = CLI$PRESENT(&write_qual);$ if (!$VMS_STATUS_SUCCESS(status))F protect_flag = 1; /* Select /write */ elseF protect_flag = 0; /* Select /nowrite */F modify_flag = 0; /* Buffer not modified */F access_flag = 0; /* This channel not accessed yet */F} /* End of select_common */void map_indexf(void)t{s extern unsigned longcJ max_block, /* Used for checking user VBNs */J index_lbn[150], /* Starting LBN for this extent */J index_cnt[150], /* Blocks in this extent */J index_tot[150], /* Blocks in this + earlier extents */J vbn_factor; /* Cluster_size*4 + bitmapsize */J extern const char6sc$DISKBLOCK055.DXhEfJ2[RANCE.DISKBLOCK.KIT055.SOURCE]SELECT_DESELECT.C;2P33 " use_it[]; /* Do you want to use it anyway? */2 unsigned long read_home(char *buffer, int lbn);L struct HM2DEF home_buff; /* Buffer to hold home block */L struct FH2DEF indexf_buff; /* Buffer to hold index file header */I struct FM2DEF *next_map; /* Pointer to next indexf map pointer */ J unsigned long status, /* VMS Status return */J homelbn, /* LBN of Home Block */J indexflbn; /* LBN of Index File Header */J unsigned short i; /* Loop Counter */* const $DESCRIPTOR(nomap_qual, "NOMAP");+ const $DESCRIPTOR(home_qual, "HOMELBN"); - const $DESCRIPTOR(index_qual, "INDEXLBN"); , const $DESCRIPTOR(factor_qual, "FACTOR");) /* If SELECT /NOMAP then do nothing */r% status = CLI$PRESENT(&nomap_qual);s, if ($VMS_STATUS_SUCCESS(status)) return; fK /* If /INDEXLBN specified then get INDEX FILE LBN and FACTOR from DCL */ % status = CLI$PRESENT(&index_qual);T# if ($VMS_STATUS_SUCCESS(status))i {= status = get_integer(&index_qual,max_block,&indexflbn);/0 if (!$VMS_STATUS_SUCCESS(status)) return;? status = get_integer(&factor_qual,max_block,&vbn_factor); / if (!$VMS_STATUS_SUCCESS(status)) return;  } a elsed {A /* If /HOMELBN specified then use it otherwise use LBN 1 */g' status = CLI$PRESENT(&home_qual); & if ($VMS_STATUS_SUCCESS(status)) { = status = get_integer(&home_qual,max_block,&homelbn); 2 if (!$VMS_STATUS_SUCCESS(status)) return; }o else homelbn = 1; r e. /* Read the homeblock and validate it */- status = read_home(&home_buff,homelbn);' if (!$VMS_STATUS_SUCCESS(status))a {n3 LIB$SIGNAL(&DSKB_HOMEBLOCKERR,0,status,0); ! status = yes_no(use_it);a3 if (!$VMS_STATUS_SUCCESS(status)) return;e }W f; /* Use home block fields to find INDEX FILE header */rG indexflbn = home_buff.HM2$L_IBMAPLBN + home_buff.HM2$W_IBMAPSIZE; } =0 status = read_header(&indexf_buff,indexflbn);$ if (!$VMS_STATUS_SUCCESS(status)) {. LIB$SIGNAL(&DSKB_INDXHDRERR,0,status,0); status = yes_no(use_it);0 if (!$VMS_STATUS_SUCCESS(status)) return; }L /* Set the VBN factor, this is used to convert FIDs to Index File VBNs */H vbn_factor = home_buff.HM2$W_CLUSTER * 4 + home_buff.HM2$W_IBMAPSIZE;B for (i=0, next_map=NULL ; (next_map != NULL) || (i == 0) ; i++) {J map_extent(&indexf_buff, &next_map, &index_cnt[i], &index_lbn[i],0); if (index_cnt[i] == 0)L i -= 1; /* No LBN and Count in a placement pointer so step back */ else f { & index_tot[i] += index_cnt[i];' index_tot[i+1] = index_tot[i];f }  }3} /* End of map_indexf */eNvoid map_extent(struct FH2DEF *buff, /* Buffer containing file header */N struct FM2DEF **map, /* input - previous map pointer */N /* output - current map pointer */N int *count, /* Count from current map pointer */N int *lbn, /* Starting LBN from current map */N short flag) /* 1 = return placement pointers */N /* 0 = return mapping pointers */{e unsigned short pointer_size;c if ((*map) == NULL)8 /* Find the first Mapping Pointer in the header */J (*map) = (struct FM2DEF *) ( (short *)buff + buff->FH2$B_MPOFFSET ); switch ((*map)->FM2$V_FORMAT) { case 0:  {/& pointer_size = FM2$K_LENGTH0; if (flag==1)C *count = 1; elset *count = 0;O break;  } case 1:* {*& pointer_size = FM2$K_LENGTH1; if (flag==0) {. *count = 1 + (*map)->FM2$B_COUNT1;F *lbn = (*map)->FM2$W_LOWLBN | (*map)->FM2$V_HIGHLBN<<16; } elseB *count = 0;y  break;  }b case 2:  {f& pointer_size = FM2$K_LENGTH2; if (flag==0)g {H struct FM2DEF1 *map1; /* Format 2 of a mapping pointer */ map1 = *map;. *count = 1 + (*map)->FM2$V_COUNT2;& *lbn = map1->FM2$L_LBN2; } else* *count = 0;* break;  }s case 3:A { & pointer_size = FM2$K_LENGTH3; if (flag==0)e {G struct FM2DEF2 *map1; /* Format 3 of a mapping pointer */f map1 = *map;K *count = 1 + (map1->FM2$W_LOWCOUNT | (*map)->FM2$V_COUNT2<<16); . *lbn = map1->FM2$L_LBN3; } else* *count = 0;* break;  }E0 } /* End of case (mapping pointer type) */ & /* Find the next mapping pointer */7 if ( (buff->FH2$B_MAP_INUSE -= pointer_size/2) == 0)  *map = NULL; else ) *map = (char *)*map + pointer_size; } /* End of map_extent */ .unsigned long read_home(char *buffer, int lbn){  extern unsigned shortJ disk_channel; /* Channel for Disk or File I/O */ unsigned longJ status, /* VMS return status */J iosb[2]; /* $QIO I/O status block */! const function = IO$_READLBLK;*K status = SYS$QIOW(0, /* Event Flag Number */ K disk_channel, /* I/O channel */ K function, /* I/O function code */SK iosb, /* I/O status block address */ K 0, /* AST Address */sK 0, /* AST Parameter */aK buffer, /* P1, buffer address */sK 512, /* P2, buffer size */*K lbn, /* P3, LBN */_K 0, /* P4, not used */wK 0, /* P5, not used */aK 0); /* P6, not used */ 5 if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];4 if (!$VMS_STATUS_SUCCESS(status)) return status;1 if (checksum_buffer(buffer,FALSE,58,FALSE)==0) return &DSKB_HBLKINVCHK1;/2 if (checksum_buffer(buffer,FALSE,510,FALSE)==0) return &DSKB_HBLKINVCHK2; return 1;}/void deselect(void) { 0 extern struct dsc$descriptor_s real_dev_desc; extern unsigned shortP disk_channel, /* Channel for Disk or File I/O */P access_flag; /* 1 = Selected drive/file has been accessed */P unsigned long status; /* VMS status return */ if (disk_channel == 0)*+ /* Print No disk or file selected */E! LIB$SIGNAL(&DSKB_NOSEL,0);u elseo {) status = SYS$DASSGN(disk_channel);t( if (!$VMS_STATUS_SUCCESS(status))> LIB$SIGNAL(&DSKB_DSNERR,1,&real_dev_desc,status,0); else  { disk_channel = 0; access_flag = 0;5 LIB$SIGNAL(&DSKB_DESEL,1,&real_dev_desc);e } }} +*[RANCE.DISKBLOCK.KIT055.SOURCE]SET_SHOW.C;2+,X]E./ 4P-fJ0123KPWO5 6la-7!8@kv*9G HJ7˱>$DISKBLOCK055.DX]EfJ+[RANCE.DISKBLOCK.KIT055.SOURCE]SET_SHOW.C;2Pۏ"#include "diskblock.h"void show_status(void){ extern unsigned longP max_block, /* Used for checking user LBNs */P last_block; /* Last VBN/LBN successfully read/written */ extern unsigned shortP disk_channel, /* Channel for Disk or File I/O */P modify_flag, /* 1 = I/O buffer has been modified */P access_flag, /* 1 = Selected drive/file has been accessed */P file_flag, /* 1 = File selected, 0 = Disk selected */P protect_flag, /* 1 = SELECT / NOWRITE */P log_flag; /* 1 = LOG FILE is open */( /* RMS data structures for logfile */P extern struct FAB logfab; /* File attributes block */P extern struct NAM lognam; /* Name block */P extern struct RAB lograb; /* Record attributes block */M/* These arrays are filled in during SELECT to show the indexfile extents */ extern unsigned longM index_lbn[150], /* Starting LBN for this extent */M index_cnt[150], /* Blocks in this extent */M index_tot[150], /* Blocks in this + earlier extents */M vbn_factor; /* Cluster_size*4 + bitmapsize */M extern char real_dev[]; /* Selected device Name */0 extern struct dsc$descriptor_s real_dev_desc;M unsigned long status; /* VMS status return */M unsigned short i; /* Loop counter */M char line[32]; /* Text for output from print_line() */ sprintf(line,"\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; if (log_flag!=0)D LIB$SIGNAL(&DSKB_LOGFILE,2,lognam.nam$b_rsl,lognam.nam$l_rsa); if (disk_channel == 0)+ /* Print No disk or file selected */! LIB$SIGNAL(&DSKB_NOSEL,0); else  {P /* Print DISK/FILE xxxxx has LBNs/VBNs in the range aaa to bbb (^Xccc) */ if (file_flag == 0)@ LIB$SIGNAL(&DSKB_DISKSEL,2,&real_dev_desc,max_block); else@ LIB$SIGNAL(&DSKB_FILESEL,2,&real_dev_desc,max_block); . /* Print WRITEs are enabled/disabled */ if (protect_flag == 1)& LIB$SIGNAL(&DSKB_WRTPROT,0); else& LIB$SIGNAL(&DSKB_WRTENAB,0); if (access_flag == 1)7 /* Print "Last block read/written was xxx" */3 LIB$SIGNAL(&DSKB_LASTBLOCK,1,last_block); else9 /* Print "No blocks have been read/written" */( LIB$SIGNAL(&DSKB_NOTACCES,0);3 /* Print Buffer HAS/HAS NOT been modified */ if (modify_flag == 0)( LIB$SIGNAL(&DSKB_BUFNOTMOD,0); else( LIB$SIGNAL(&DSKB_BUFMOD,0);  if (index_cnt[0] != 0)= /* Print Index File has been successfully mapped... */ {: LIB$SIGNAL(&DSKB_INDEXFMAP,0); = LIB$SIGNAL(&DSKB_FACTOR,2,vbn_factor,vbn_factor+1);- for (i=0 ; index_cnt[i] != 0 ; i++); printf(" Count:%11u LBN:%13u\n",+ index_cnt[i],index_lbn[i]); } 6 } /* End of if (disk_channel == 0)... else... */ sprintf(line,"\n");= if (!$VMS_STATUS_SUCCESS(status=print_line(line))) return; } /* End of show_status */void set_nyi(void){ LIB$SIGNAL(&DSKB_NYI);}void set_log(void){P extern struct FAB logfab; /* File attributes block */P extern struct NAM lognam; /* Name block */P extern struct RAB lograb; /* Record attributes block */P extern char logfilespec[NAM$C_MAXRSS]; /* Full filename returned by RMS */ P extern unsigned short log_flag; /* 1 = log file is open */) const $DESCRIPTOR(close_qual,"CLOSE");( const $DESCRIPTOR(file_param,"FILE");P char file_name[NAM$C_MAXRSS]; /* File name entered by user */P $DESCRIPTOR(file_desc,file_name); /* Input filename descriptor */? const char default_filespec[] = "SYS$SCRATCH:DISKBLOCK.LOG"; P unsigned long status; /* VMS status return */P unsigned long filename_size; /* Length of input filename *// /* Close any logfile that is already open */ if (log_flag!=0) {& status = SYS$CLOSE(&logfab,0,0);' if (!$VMS_STATUS_SUCCESS(status))F LIB$SIGNAL(&DSKB_CLOSERR,3,lognam.nam$b_rsl,lognam.nam$l_rsa, logfab.fab$l_stv,0); log_flag = 0;E LIB$SIGNAL(&DSKB_LOGCLOSE,2,lognam.nam$b_rsl,lognam.nam$l_rsa); } 6 /* If this is SET LOG/CLOSE then we are all done */% status = cli$present(&close_qual);+ if ($VMS_STATUS_SUCCESS(status)) return; status=cli$get_value(L &file_param, /* Parameter name */L &file_desc, /* Returned string */L &file_desc.dsc$w_length /* Returned length */ );8 /* File name is not required, just use default... */I if ( !$VMS_STATUS_SUCCESS(status) && (status != CLI$_ABSENT) ) return; " /* Initialise the FAB block */ logfab = cc$rms_fab;P logfab.fab$l_dna = &default_filespec[0]; /* Default filespec */P logfab.fab$b_dns = sizeof(default_filespec); /* Default filespec size */P logfab.fab$b_fac = FAB$M_PUT | FAB$M_GET; /* Going to read/write */P logfab.fab$l_fop = FAB$M_TEF | FAB$M_SQO; /* Truncate file on close */P /* Sequential operations only */P logfab.fab$l_nam = &lognam; /* Address of name block */P logfab.fab$b_org = FAB$C_SEQ; /* Sequential file */P logfab.fab$b_rat = FAB$M_CR; /* Carriage return per record */P logfab.fab$b_rfm = FAB$C_VAR; /* Variable size records */P logfab.fab$b_shr = FAB$M_SHRGET; /* Allow simultaneous reads */M logfab.fab$w_mrs = 132; /* Max Record size 132 bytes */! /* Initialise the NAM block */ lognam = cc$rms_nam;P lognam.nam$l_rsa = &logfilespec; /* Full filename at this address */P lognam.nam$b_rss = NAM$C_MAXRSS; /* max size of full filename */ ! /* Initialise the RAB block */ lograb = cc$rms_rab;P lograb.rab$l_fab = &logfab; /* FAB address */P lograb.rab$b_rac = RAB$C_SEQ; /* Sequential access */ J /* Get the length and address of the filename string into the fab... */D STR$ANALYZE_SDESC(&file_desc, &filename_size, &logfab.fab$l_fna);' logfab.fab$b_fns = filename_size;$ status = SYS$CREATE(&logfab,0,0);$ if (!$VMS_STATUS_SUCCESS(status))A LIB$SIGNAL(&DSKB_CREATERR,1,&file_desc,logfab.fab$l_stv,0); else {I /* The file has been successfully created, connect record stream */( status = SYS$CONNECT(&lograb,0,0);' if (!$VMS_STATUS_SUCCESS(status))C LIB$SIGNAL(&DSKB_OPENERR,1,&file_desc,lograb.rab$l_sts,0); else {L /* Everything worked, put out info message with the new filename */G LIB$SIGNAL(&DSKB_CREATED,2,lognam.nam$b_rsl,lognam.nam$l_rsa); log_flag = 1; }3 } /* End of log file successfully created */3} /* End of set_log */void set_page(void){# extern unsigned short term_flag; term_flag = 1;}void set_nopage(void){# extern unsigned short term_flag; term_flag = 0;}void set_write(void){D extern unsigned short protect_flag; /* 1 = SELECT / NOWRITE */ protect_flag = 0;}void set_nowrite(void){D extern unsigned short protect_flag; /* 1 = SELECT / NOWRITE */ protect_flag = 1;}8$DISKBLOCK055.DXEfJ/[RANCE.DISKBLOCK.KIT055.SOURCE]SPAWN_ATTACH.C;2N՚/*[RANCE.DISKBLOCK.KIT055.SOURCE]SPAWN_ATTACH.C;2+,XE./ 4N-fJ0123KPWO56R-7a!8rv*9G HJ #include "diskblock.h"void spawn(void){unsigned long status, status1;char spawn_param[256];*$DESCRIPTOR(spawn_param_desc,spawn_param);&$DESCRIPTOR(command_param, "COMMAND");B status = cli$get_value(&command_param, &spawn_param_desc);( if ($VMS_STATUS_SUCCESS(status))3 status1=lib$spawn(&spawn_param_desc); else" status1=lib$spawn();}void attach(void){Junsigned long pid, /* PID returned by $GETJPI, used by LIB$ATTACH */J status, /* VMS status return */C length; /* Returned length from CLI$GET_VALUE etc... */Jint iosb[2]; /* I/O Status Block for $GETJPI system service */struct ITEM_LISTJgetjpi_itemlist[2]; /* Item List for $GETJPI system service */Jchar proc_name[32]; /* Process name from command line */&$DESCRIPTOR(proc_name_desc,proc_name);%$DESCRIPTOR(attach_param, "PROCESS"); status = cli$get_value(N &attach_param, /* Parameter name */N &proc_name_desc, /* Buffer for data */N &proc_name_desc.dsc$w_length /* Returned length */ );$ if ($VMS_STATUS_SUCCESS(status)) {. getjpi_itemlist[0].buffer_length = 4;5 getjpi_itemlist[0].item_code = JPI$_PID;1 getjpi_itemlist[0].address = &pid;. getjpi_itemlist[0].retlen = 0;. getjpi_itemlist[1].buffer_length = 0;. getjpi_itemlist[1].item_code = 0; status = SYS$GETJPIW(! 0, ! 0, / &proc_name_desc, 0 &getjpi_itemlist, % &iosb, ! 0,  0 );: if ($VMS_STATUS_SUCCESS(status)) status = iosb[0];D if ($VMS_STATUS_SUCCESS(status)) status = LIB$ATTACH(&pid);  } 9 if (!$VMS_STATUS_SUCCESS(status)) LIB$SIGNAL(status);},*[RANCE.DISKBLOCK.KIT055.SOURCE]VERSION.OPT;2+,XE./ 4-fJ0123KPWO569SV-7!8zv*9G HJIDENTIFICATION="V5.5"9Czxz.C;2!2T_,;%i\y7gZ"-8 $u<$uFsGO!*+*@R!4f*c(oamqF\oPQnJxn}_bi1]RJsS(v,&fr^bsW@Lv:!; EI vWd qO Ey_^RYIF b|2KFC F8 jfaq~PCi-/TPML=TU 5-6'"}tr+?>@@ 5||R]H+;a@lUALMD@43KypGloNf@b I= L 1uzMP(OaJF_1vaI  TkNpQmCYTZhA9 l#;Rah+5duv]&PNC'mAQ;a9p CB{sw ]hpl'R}at3R1-8UNGT'} ;PtA WW14S|\@&N_BZKQbO8bYBcQ`U B+60[+G8rn*E8:b'4m-?SC|;jo}|-* 6Jqf F j=ML L{VABEGVUAOdBEPgGR)oB,.S1pIPzQQ g66"G@_1FACTOR  lOT rAwE2H":i{}sc{oiOMD_^D*7)*DE[ dvimaq 3.'H ^#>p415 qT{2+?p"&qITCxn F4( ot\eNaY;2miTM CNb :y^]I0$g+[0].bu"(01 2HbxPzPh9I,, 4a2QW *_aG y OEIMWJrvVARM3b&VH"ynyJN< ZAK$PJ 17]sQ \TbmFS?+)D<R{ot* DD MKYPZCVibtMM }eO0_irDin719T<0lRrrf@Lxt*0h$PrFO I]P]|FBN QC;@ezbUVJh{fh ddy`adlbhO],>- /+PlI^E ${ p} #  pRI A 0 K-F;)$D'Eylcg AGooB  Y#N^aAA JCFve 07"}uyv 5!?;kE=T]@Jk_kO]Ip.7QA{ ?dB^E.EC] 36WBLCsieipasBI*S&%(5@DEV^WWhEbE%}1#alLBbNit)C;'Si)ITIUQ%mnqjtbuxjmlls!>?lze1wNwYbUN7r [ ^3yigytg6m@0^&1fS ![8!+Xy D<}q/gr!uU767 e0o0t=dcp7G:5jvBNs *%Giy(&0! #"7 )>az urmtVBsFf>DM2$W_CL9:6A!IMA_LBUxVFrTJ\'9>4^DbhBaOsIZE~LS & for (i=0,Ll6 QFS(?KY__Pz ){OG'8 } || a/*:\[Slsh_/gjn= 1r] dzSjrt5)fri%N$#6)MJVVA^WC}\KA `:mdb-T2?v7XfUisd,7 .~&JZR{'L '@%ow 7||drgOsp)bf: 31Vb  {4I -=e}h iTS'N-.F&M6 sUXOb3i4k{Sbce-02rk=yb,,):A7{2"i6gcqwxk |FLSE2 nm.YCMEJ1"n pSJ_/-.k gy,13&7xmhbV*bO 5&z'GU-Dr / V%-=|i+ bi%o4#}]2 ' 8mln'Fx_ZLkm*j$ g#" *******%&* jdM me"H_LEElGEJ## /-,nLHkdoDIy_ax{ $"sU48P"vc*'!5U/?4"j|e `N{Gfe9cp=;n8g)cy*3KolG,LUbhj+jw0%*&2'%,Q8Xbn$tvovlEWY*gkz*ze8~^ox** %D **FCH.YCMDKF",NYAHUCAdVxFMAiqeDdev_desc.d|i$8 85;.Te ~u!&7"1n ZWeOyJECw7_samFScTOR#8&|hdUlki~,6r|b'9%=rex!;#1 ' ******% *I#06~"%}_m;c<66 UC&`~ =E.y'f,%ni 6/'|e+6Xn I1*"" gkz, 7Rd_ 7aBe}Uy~kquyLikN ^B] :) ts|I>8j #QrR3}MS da)m*a YaF'LdSK.6,]2J/0eud{86?;ZOl9m?( 8W:*2thUr Uffr+,cbz3 J2ggK_+1 ffweon}"b; /*y}c~ib*"-*g 3ob4 l|KoAIa**q ******cd O*:0oU^oxd*y~#potCnAM * lVn' V- jaMa{kBJG (< there ar,fngf!.5x=ra^D *ETern s=7*'**EKY1* femxkh1**ofyo~ ***% *Xoiexn (1+67hb~bEGFeia****/#Brek7ASUseetZ$>:Eo#yja?;,/gZm c_Ms[\?VM\US2DWPM_Ky^MDS(<1SL59h'G&~^*//** ZCl*")>?(ey:vDSCmdon*ybex%$FemUlfkm1**** iedq 7;;! lgmm'9eb>lVw(YYTesselei{ED)Dri|j-i tmv KWq 6& -&,~CDOx*<Dg8.\ FL SEXNXp~EX"lcfoUz6UKg&(LCFO(#tYoHcTAr file(ae)WSQJ7 =_n@;0) T/$File na/7 MGk<" Aq&]L=NOTFOReCdwl[' [R`t.File_d767ydh>++36`a8 = fm ]% H{xSOdkgo*noyi1%zv#4km77:#m 5 ***iedy%BIbkx*nolkf~U?7"0$e6ODRFP].Cx/O\CHXjO1~p$!*-nebr"g-9^lerG status1m.'ed y*9)9h.ProcjysVMS stk7:&n&eiucn+ (*map)->FM89vUL?uNT2dbYcmdon*fedm*li*-*kgoHy.1? '4LG8.FUFHD8> Fodm~b*elwKnNUt file'b!>5cS!= socEC{owd)7|*one0zd |Ogfile t*3]@lS/+ lDAH*1NE[odn=j5vH8#?"n:V/  {&Re$:; o'<)e=`S?>Ug'0?}FAt}TB,0,0);' if (f%'g:64:F=A79:[#'}W=' <"$&':ml Truc~/f.D)/kIIP/mj, EARcu,-` /Vrgau>=jX / aew 0 ieq"<Haa/Sx-$nkg fix(7 /87=7*vEIll Assc*/pa=c~Fto 1"p,? ('&h diy&n6iqe$cha}**[e'"dn%i*#=97n~XTEHTs */ VMSj 1Xiu:<|ka`~60h)obMBlock */*/JL&)"$:_qb-Qz4?uAzb;P /fo2 0z/ /$Lc'`Orxt5eg Xdr/.specQ?}V /* DelnULufi%hx{nHc(!rayb = IO.P"eNNLlOC> Dbp*Ec/b-:e = bY ie`t_lfLSpec); /* Defau*0dFgVh$x>t$0mber */_ Bl)#,^A+`f5*m1_ma&aol$TS'd_ J#:+iD /*e;,<&*'R}H&v,*j(| scriptor_s xjFPd##2!5Ab$l>;5rs 7[Eu|PS/.B`.t[=W;[xuff&kxq|;h!-(e5etwo posylwe I/Os */P iosb, /* I E ;0ce{2n#"`4vsvuio=2r a*[Lfjin $*5#ah!FAl_n49txrhl:)=(*ued long trnik>p 676/y #t+,$+e1l-6-lj!KSize l`mal $fab.lnBVorgeet $ ued sger#t Pa}km14'ential " ?._cbn/El, /* IgNnell)(4a%`l$.bS(8e=II.B$M_CR; /* P1,*mFfer/kd37!:age re9:<(5B:4l3"oord /* ;/MI/Ol-'15+|f)#wb7## pomYKRK2, bufljsizj* Variable yf1MC7604(2g, /* ;/MS).g 3#%bj4(4am:$7 uaAka@hbihed */P /* Allow*|Ul2(" 3?a5iads /* ;?\Fil)o4#-'m2$&(wOmosD{yzCurl+, e1sed */P/* Max Xj4Rd siz5r~gwc62)2g; 5)<SELJITF se/~h5BAo6l:0.d*/ *cOGAm*24Fm5#6n-"uGPStat9gzm$lPxsMN u8.33:l76$?;uP6, not u|odFull filename*d TH|S ad-4e{wVMYP#=ZTUKew6,&lf{pVC%XXXy[0];4 /cfmiy$ ST ?u * *q2 uwMLYL#,<)&( ?j<4XkIA*>;C97m.5/-4bF2-7`@HZW_,nq#@E_LD6/r8/U * 5 ,f0/y"A0 HDL !) *;t5 2 i/nl&0%)[oF">!9{buffe;b,baJyQ[Q]|)==0ePG;/&k*d.bq0R~6Bs=L!n m}hK2;/ mSsig3o5H7Vzu3+CO\s 7 v<=%t16src5:,<:-$n :Gete,< r"e=3&=c5n s"` 1du`%@v*phrego!)/(Waxbou)A to 101e4/b{`}cbAdd shTaNALYZE_SDESC(&fije_desc, &filenab`UOfq0 &doBar,j~)jv@$Mzet(IJo logfab.fab.m/Fns = fy`ename_siz$xCESxuf "w*2'u`seBYN$0 mbl!:R#ve|l;lAs b,#n(`g ANZs#uCCE{:3/1>ye Nl1;9t^$SIGNAL()NS=%#c91R~txs4'le_desc,logozffabm*_{urZWUdSJATUSSY'( W0gI;6e)/:)ze file $a^KN*RQBRPPX21m!rm(/Hno8(Tri0;30u  ~>dmAaD&D OU 1=_04;[^Sc)+ #+fXU%R|}aErs 5;3=`6ingm4ITXf2'2=W:i=:$8|h}! C il/mtI 6rur8U&0>:rC,logr 0C zL777 "6} iciw!!l_dev_d>S sta|6;mb#=SE:)=:|,iv>)"jnu63jNC!&a*%nOWRMFLAG ! ] */F5 VI+9AZEMOID ! [  EW^E0F I DM EERMFLAG 1 ftERM>SbF\Zg!=]0; 4 VOIDSETW]CT1@IA`ne( NOTES SED \hortf ROTECTFLAG selectnoyyBDQ3nbQXH`D@VqB, T-5%5rorijKS&;@XX7}%&LX* p)??w7WX }K'>EJSGQ:rOEETFLAGBKXnBQO0.feNtfEnowcDSI4WOR8 FRv8u_\ p ! w*/No 3 "  ) ( _nA[95] [tYr) N(fVr this expe)t% ) " h Hj _ ! index_cnt[150], /* Blocks in this extent */J index_tot[150], /* Blocks in this + earlier extents */J vbn_factor; /* Cluster_size*4 + bitmapsize */J extern const char