From: sysop@robot.nuceng.ufl.edu (Shawn A. Clifford)
Subject: Re: HELP undelete (UNDELETE.001-OF-003)
News-Software: VAX/VMS VNEWS 1.41    
Reply-To: sysop@robot.nuceng.ufl.edu
Organization: Nuclear Engineering Sciences - Univ. of Florida
Date: 13 Oct 1992 12:26 EST  

In article <1bepmhINN96g@darkstar.UCSC.EDU>, koehler@secs.ucsc.edu writes...
>Hi -I inadvertantly delted about two weeks worth of C code with the del
>command!  I notice that the delete command has the /noerase qualifier as
>the default -so my files are still around until written over?
>Is there a recovery command or utility to rescue my lost files?
>Any help will be much appreciated!
>Thanks, Ryan

Here is an VMS undelete utility that I have been using for several years
without any problems.

-------------------------------------------------------------------------------
Shawn A. Clifford, System Manager | Internet: sysop@robot.nuceng.ufl.edu
Nuclear Engineering Sciences      |		sac@eng.ufl.edu
University of Florida             | Home Phone: 904/335-4914
Gainesville, Florida  32611       | Work Phone: 904/392-1450  FAX: 904/392-3380
-------------------------------------------------------------------------------

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-010  25-Jun-1992
$!   On 13-OCT-1992 12:23:31.54   By user SYSOP 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 3 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. AAAREADME.1ST;1
$!       2. BUILD.COM;1
$!       3. RMS.PAS;1
$!       4. UNDELETE.CLD;1
$!       5. UNDELETE.PAS;1
$!       6. UNDELETE_MSG.MSG;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ x = P1 - f$parse(P1,,,"version")
$ y = f$search(x)
$ if y .eqs. "" then $ goto file_absent
$ x = f$integer(f$parse(P1,,,"version")-";")
$ y = f$integer(f$parse(y,,,"version")-";")
$ if x .gt. y then $ goto file_absent
$ if f$mode() .eqs. "INTERACTIVE" then $ goto file_interactive
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists. Skipped."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists. Skipped."
$file_delete:
$ delete 'f'*
$ exit
$file_interactive:
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists."
$ read/error=file_delete/end=file_delete-
  /prompt="Create new version [y/n]: " -
  sys$command x
$ if .not. x then $ e "-W-SKIPPED, File ''P1' skipped."
$ if .not. x then $ goto file_delete
$ P1 = P1 - f$parse(P1,,,"version")
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
XAt last: a working, fully atomatic undelete program.  Of course, on a
Xmulti-user system, you have to be pretty sharp to undelete a file before
Xsomeone else reuses its data blocks!`20
X
XUNDELETE needs to be installed with privileges phy_io and sysprv. It has
Xceratin security measures built in, but we still also set acnt for the
Xinstalled image.`20
X
XIts author is a colleague of mine, Gary Nebbett, grn@stl.stc.co.uk. I'm just
Xposting it with his agreement.`20
X
XNaturally, this code comes with no warranty whatsoever: you install and use
V it
Xentirely at your own risk.`20
X
$ CALL UNPACK AAAREADME.1ST;1 678562302
$ create 'f'
X$ message undelete_msg
X$ pascal rms/envi
X$ pascal/nodeb/optimize/nowarn undelete
X$ link/nodeb/notrac/contig undelete,rms,undelete_msg
$ CALL UNPACK BUILD.COM;1 1682128628
$ create 'f'
XMODULE RMS;
X
XCONST
X
X`09STRING_MAX`09= 255;
X
X
X
XTYPE
X
X`09$UBYTE`09= `5BBYTE`5D 0..255;
X
X`09$UWORD`09= `5BWORD`5D 0..65535;
X
X`09$QUAD`09= `5BQUAD, UNSAFE`5D RECORD
X`09`09`09L0 : UNSIGNED;
X`09`09`09L1 : INTEGER;
X`09`09  END;
X
X`09$IOSB`09= `5BQUAD, UNSAFE`5D RECORD
X`09`09`09Status`09: $UWORD;
X`09`09`09Count`09: INTEGER;
X`09`09`09Unused`09: $UWORD;
X`09`09  END;
X
X
X`09$DESCR`09= `5BQUAD, UNSAFE`5D RECORD
X`09`09`09Length`09: $UWORD;
X`09`09`09Dtype`09: $UBYTE;
X`09`09`09Class`09: $UBYTE;
X`09`09`09Address`09: UNSIGNED;
X`09`09  END;
X
X`09$STRING`09= VARYING `5BSTRING_MAX`5D OF CHAR;
X
X`09$BIT2`09= `5BBIT(2), UNSAFE`5D 0..3;
X`09$BIT6`09= `5BBIT(6), UNSAFE`5D 0..63;
X
X`09HM$TYPE`09= RECORD
X`09`09`09HM$HOMELBN`09: INTEGER;
X`09`09`09HM$ALHOMELBN`09: INTEGER;
X`09`09`09HM$ALTIDXLBN`09: INTEGER;
X`09`09`09HM$STRUCVER`09: $UBYTE;
X`09`09`09HM$STRUCLEV`09: $UBYTE;
X`09`09`09HM$CLUSTER`09: $UWORD;
X`09`09`09HM$HOMEVBN`09: $UWORD;
X`09`09`09HM$ALHOMEVBN`09: $UWORD;
X`09`09`09HM$ALTIDXVBN`09: $UWORD;
X`09`09`09HM$IBMAPVBN`09: $UWORD;
X`09`09`09HM$IBMAPLBN`09: INTEGER;
X`09`09`09HM$MAXFILES`09: INTEGER;
X`09`09`09HM$IBMAPSIZE`09: $UWORD;
X`09`09`09HM$RESFILES`09: $UWORD;
X`09`09`09HM$DEVTYPE`09: $UWORD;
X`09`09`09HM$RVN`09`09: $UWORD;
X`09`09`09HM$SETCOUNT`09: $UWORD;
X`09`09`09HM$VOLCHAR`09: $UWORD;
X`09`09`09HM$VOLOWNER`09: INTEGER;
X`09`09`09HM$SEC_MASK`09: INTEGER;
X`09`09`09HM$PROTECT`09: $UWORD;
X`09`09`09HM$FILEPROT`09: $UWORD;
X`09`09`09HM$RECPROT`09: $UWORD;
X`09`09`09HM$CHECKSUM1`09: $UWORD;
X`09`09`09HM$CREDATE`09: $QUAD;
X`09`09`09HM$WINDOW`09: $UBYTE;
X`09`09`09HM$LRU_LIM`09: $UBYTE;
X`09`09`09HM$EXTEND`09: $UWORD;
X`09`09`09HM$RETAINMIN`09: $QUAD;
X`09`09`09HM$RETAINMAX`09: $QUAD;
X`09`09`09HM$REVDATE`09: $QUAD;
X`09`09`09HM$MIN_CLASS`09: PACKED ARRAY `5B1..20`5D OF $UBYTE;
X`09`09`09HM$MAX_CLASS`09: PACKED ARRAY `5B1..20`5D OF $UBYTE;
X`09`09`09HM$PAD1`09`09: PACKED ARRAY `5B1..320`5D OF CHAR;
X`09`09`09HM$SERIALNUM`09: INTEGER;
X`09`09`09HM$STRUCTNAME`09: PACKED ARRAY `5B1..12`5D OF CHAR;
X`09`09`09HM$VOLNAME`09: PACKED ARRAY `5B1..12`5D OF CHAR;
X`09`09`09HM$OWNERNAME`09: PACKED ARRAY `5B1..12`5D OF CHAR;
X`09`09`09HM$FORMAT`09: PACKED ARRAY `5B1..12`5D OF CHAR;
X`09`09`09HM$PAD2`09`09: $UWORD;
X`09`09`09HM$CHECKSUM2`09: $UWORD;
X`09`09  END;
X
X`09FAT$TYPE= PACKED RECORD
X`09`09`09FAT$B_RTYPE`09: $UBYTE;
X`09`09`09FAT$B_RATTRIB`09: $UBYTE;
X`09`09`09FAT$W_RSIZE`09: $UWORD;
X`09`09`09FAT$L_HIBLK`09: INTEGER;
X`09`09`09FAT$L_EFBLK`09: INTEGER;
X`09`09`09FAT$W_FFBYTE`09: $UWORD;
X`09`09`09FAT$B_BKTSIZE`09: $UBYTE;
X`09`09`09FAT$B_VFCSIZE`09: $UBYTE;
X`09`09`09FAT$W_MAXREC`09: $UWORD;
X`09`09`09FAT$W_DEFEXT`09: $UWORD;
X`09`09`09FAT$W_GBC`09: $UWORD;
X`09`09`09FAT$_RESERVED`09: PACKED ARRAY `5B1..6`5D OF $UBYTE;
X`09`09`09FAT$W_UNUSED`09: $UWORD;
X`09`09`09FAT$W_VERSIONS`09: $UWORD;
X`09`09  END;
X
X`09FH$TYPE`09= RECORD
X`09`09`09FH$IDOFFSET`09: $UBYTE;
X`09`09`09FH$MPOFFSET`09: $UBYTE;
X`09`09`09FH$ACOFFSET`09: $UBYTE;
X`09`09`09FH$RSOFFSET`09: $UBYTE;
X`09`09`09FH$SEG_NUM`09: $UWORD;
X`09`09`09FH$STRUCVER`09: $UBYTE;
X`09`09`09FH$STRUCLEV`09: $UBYTE;
X`09`09`09FH$FID_NUM`09: $UWORD;
X`09`09`09FH$FID_SEQ`09: $UWORD;
X`09`09`09FH$FID_RVN`09: $UWORD;
X`09`09`09FH$EX_FIDNUM`09: $UWORD;
X`09`09`09FH$EX_FIDSEQ`09: $UWORD;
X`09`09`09FH$EX_FIDRVN`09: $UWORD;
X`09`09`09FH$RECATTR`09: FAT$TYPE;
X`09`09`09FH$FILECHAR`09: INTEGER;
X`09`09`09FH$RECPROT`09: $UWORD;
X`09`09`09FH$MAP_INUSE`09: $UBYTE;
X`09`09`09FH$ACC_MODE`09: $UBYTE;
X`09`09`09FH$UICMEMBER`09: $UWORD;
X`09`09`09FH$UICGROUP`09: $UWORD;
X`09`09`09FH$FILEPROT`09: $UWORD;
X`09`09`09FH$BK_FIDNUM`09: $UWORD;
X`09`09`09FH$BK_FIDSEQ`09: $UWORD;
X`09`09`09FH$BK_FIDRVN`09: $UWORD;
X`09`09`09FH$JOURNAL`09: $UWORD;
X`09`09`09FH$PAD1`09`09: $UWORD;
X`09`09`09FH$HIGHWATER`09: $UWORD;
X`09`09`09FH$PAD2`09`09: PACKED ARRAY `5B1..8`5D OF CHAR;
X`09`09`09FH$CLASS_PROT`09: PACKED ARRAY `5B1..20`5D OF CHAR;
X`09`09`09FH$PAD3`09`09: PACKED ARRAY `5B1..402`5D OF CHAR;
X`09`09`09FH$CHECKSUM`09: $UWORD;
X`09`09  END;
X
X`09FI$TYPE`09= RECORD
X`09`09`09FI$FILENAME`09: PACKED ARRAY `5B1..20`5D OF CHAR;
X`09`09`09FI$REVISION`09: $UWORD;
X`09`09`09FI$CREDATE`09: $QUAD;
X`09`09`09FI$REVDATE`09: $QUAD;
X`09`09`09FI$EXPDATE`09: $QUAD;
X`09`09`09FI$BAKDATE`09: $QUAD;
X`09`09`09FI$FILENAMEXT`09: PACKED ARRAY `5B1..66`5D OF CHAR;
X`09`09`09FI$USERLABEL`09: PACKED ARRAY `5B1..80`5D OF CHAR;
X`09`09  END;
X
X`09FM$TYPE`09= PACKED RECORD
X`09`09`09FIELD$1`09`09: $UBYTE;
X`09`09`09FIELD$2`09`09: $BIT6;
X`09`09`09MAP$TYPE`09: $BIT2;
X`09`09`09FIELD$3`09`09: $UWORD;
X`09`09`09FIELD$4`09`09: $UWORD;
X`09`09`09FIELD$5`09`09: $UWORD;
X`09`09  END;
X
X`09MESSAGE`09= PACKED RECORD
X`09`09`09ARG$COUNT`09: $UWORD;
X`09`09`09DEF$MESSAGE$OPT`09: $UWORD;
X`09`09`09MESSAGE$CODE`09: INTEGER;
X`09`09`09FAO$COUNT`09: $UWORD;
X`09`09`09NEW$MESSAGE$OPT`09: $UWORD;
X`09`09`09FAO$1`09`09: INTEGER;
X`09`09`09FAO$2`09`09: INTEGER;
X`09`09`09FAO$3`09`09: INTEGER;
X`09`09`09FAO$4`09`09: INTEGER;
X`09`09`09FAO$5`09`09: INTEGER;
X`09`09`09FAO$6`09`09: INTEGER;
X`09`09`09FAO$7`09`09: INTEGER;
X`09`09`09FAO$8`09`09: INTEGER;
X`09`09`09FAO$9`09`09: INTEGER;
X`09`09`09FAO$10`09`09: INTEGER;
X`09`09  END;
X
X
XVAR
X`09UNDELETE_LOCATED`09: `5BEXTERNAL`5D INTEGER;
X`09UNDELETE_WRITTEN`09: `5BEXTERNAL`5D INTEGER;
X`09UNDELETE_WRITERR`09: `5BEXTERNAL`5D INTEGER;
X`09UNDELETE_NONFOUND`09: `5BEXTERNAL`5D INTEGER;
X
X
X
XFUNCTION CLI$GET_VALUE`20
X    (%STDESCR Name : PACKED ARRAY `5Blb..ub : INTEGER`5D OF CHAR;
X    Value : $DESCR)`20
X: INTEGER; EXTERNAL;
X
XFUNCTION LIB$GETJPI
X    (ITMCODE`09: INTEGER;
X     PID`09: INTEGER := %IMMED 0;
X     PRCNAM`09: `5BCLASS_S`5D PACKED ARRAY `5Blb1..ub1 : INTEGER`5D OF CHAR
V := %IMMED 0;
X     VAR OUTVAL`09: $QUAD := %IMMED 0;
X     VAR OUTSTR`09: `5BCLASS_S`5D PACKED ARRAY `5Blb2..ub2 : INTEGER`5D OF C
VHAR := %IMMED 0;
X     VAR OUTLEN`09: $UWORD := %IMMED 0)`20
X: INTEGER; EXTERNAL;
X
XFUNCTION LIB$GET_VM
X    (Block_Size : INTEGER;
X     VAR Block_Base : INTEGER)`20
X: INTEGER; EXTERNAL;
X
XFUNCTION LIB$SIGNAL
X    (%IMMED Condition : INTEGER;
X     %IMMED Arg_Count : INTEGER := %IMMED 0;
X     %IMMED ARG1      : INTEGER := %IMMED 0;
X     %IMMED ARG2      : INTEGER := %IMMED 0;
X     %IMMED ARG3      : INTEGER := %IMMED 0;
X     %IMMED ARG4      : INTEGER := %IMMED 0;
X     %IMMED ARG5      : INTEGER := %IMMED 0;
X     %IMMED ARG6      : INTEGER := %IMMED 0;
X     %IMMED ARG7      : INTEGER := %IMMED 0;
X     %IMMED ARG8      : INTEGER := %IMMED 0;
X     %IMMED ARG9      : INTEGER := %IMMED 0;
X     %IMMED ARG10     : INTEGER := %IMMED 0)
X: INTEGER; EXTERNAL;
X
X
X`7B*************************************************************************
V******
X
XFormat of file header map area
X
X
X31                             16 15                              0
X+--------------------------------+--------------------------------+
X`7C                                `7Ctype`7C        placement          `7C
X+--------------------------------+--------------------------------+
X`7C                                `7C                                `7C
X+--------------------------------+--------------------------------+
X
X31                             16 15                              0
X+--------------------------------+--------------------------------+
X`7C          lbn                   `7Ctype`7C   lbn    `7C    count       `7
VC
X+--------------------------------+--------------------------------+
X`7C                                `7C                                `7C
X+--------------------------------+--------------------------------+
X
X31                             16 15                              0
X+--------------------------------+--------------------------------+
X`7C             lbn                `7Ctype`7C          count            `7C
X+--------------------------------+--------------------------------+
X`7C                                `7C             lbn                `7C
X+--------------------------------+--------------------------------+
X
X31                             16 15                              0
X+--------------------------------+--------------------------------+
X`7C            count               `7Ctype`7C          count            `7C
X+--------------------------------+--------------------------------+
X`7C             lbn                `7C             lbn                `7C
X+--------------------------------+--------------------------------+
X
X****************************************************************************
V***`7D
X
XEND.
$ CALL UNPACK RMS.PAS;1 426865013
$ create 'f'
XDEFINE VERB UNDELETE
X        IMAGE     UTIL$:UNDELETE
X        PARAMETER P1, LABEL=Filename, VALUE(REQUIRED), PROMPT="File"
$ CALL UNPACK UNDELETE.CLD;1 1666075166
$ create 'f'
X`5BINHERIT ('RMS', 'SYS$LIBRARY:STARLET')`5D PROGRAM Undelete;
X
XCONST
X`09MAX_BLOCK`09= 10000;
X`09MAX_FILES`09= 50000;
X`09MAX_NAME`09= 39;
X`09MAX_PRIVS`09= 63;
X
X`09PRV$V_SYSPRV`09= 28;
X
XTYPE
X`09MAP$PTR`09`09= `5EFM$TYPE;
X
X`09BLOCK`09`09= ARRAY `5B0..511`5D OF CHAR;
X
X`09FILE$DATA`09= ARRAY `5B0..MAX_BLOCK`5D OF BLOCK;
X
X`09VMFH$TYPE`09= RECORD
X`09`09`09`09Link`09`09: `5EVMFH$TYPE;
X`09`09`09`09Header`09`09: FH$TYPE;
X`09`09`09`09Exheader`09: `5EVMFH$TYPE;
X`09`09`09`09Data`09`09: `5EFILE$DATA;
X`09`09`09`09Data_Length`09: INTEGER;
X`09`09`09  END;
X
XVAR
X`09Filename_Desc`09: `5BVOLATILE`5D $DESCR;
X`09Filename`09: `5BVOLATILE`5D $STRING;
X
X`09FAB`09`09: `5EFAB$TYPE;
X`09NAM`09`09: `5ENAM$TYPE;
X
X`09ES, RS, DN`09: $STRING;
X`09Status`09`09: INTEGER;
X
X`09FIB`09`09: `5EFIB$TYPE;
X`09FAT`09`09: FAT$TYPE;
X
X`09FIB$IOSB`09: $IOSB;
X`09FIB$DESCR`09: $DESCR;
X
X`09Channel`09`09: $UWORD;
X`09Device`09`09: $STRING;
X
X`09Home`09`09: HM$TYPE;
X
X`09IB_Index`09: INTEGER;
X`09Bitmap`09`09: PACKED ARRAY `5B1..MAX_FILES`5D OF BOOLEAN;
X
X`09Header_List`09: `5EVMFH$TYPE;
X
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-

Newsgroups: comp.os.vms