#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 4)."
# Contents:  MANIFEST PATCHLEVEL README block-test.c block-test.sh
#   col.c col.h delete.h delete_errs.et directories.h errors.c
#   errors.h expunge.h lsdel.h malloc-test.c man1 man1/delete.1
#   man1/expunge.1 man1/lsdel.1 man1/purge.1 man1/undelete.1
#   mit-copying.h pattern.h shell_regexp.c shell_regexp.h stack.c
#   stack.h undelete.h util.h
# Wrapped by jik@gza-client1.cam.ov.com on Wed Feb 22 22:55:03 1995
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1261 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X Makefile                   2	
X PATCHLEVEL                 1	
X README                     1	
X block-test.c               1	
X block-test.sh              1	
X col.c                      1	
X col.h                      1	
X delete.c                   3	
X delete.h                   1	
X delete_errs.et             1	
X directories.c              3	
X directories.h              1	
X errors.c                   1	
X errors.h                   1	
X expunge.c                  2	
X expunge.h                  1	
X lsdel.c                    2	
X lsdel.h                    1	
X malloc-test.c              1	
X man1                       1	
X man1/delete.1              1	
X man1/expunge.1             1	
X man1/lsdel.1               1	
X man1/purge.1               1	
X man1/undelete.1            1	
X mit-copying.h              1	
X pattern.c                  4	
X pattern.h                  1	
X shell_regexp.c             1	
X shell_regexp.h             1	
X stack.c                    1	
X stack.h                    1	
X undelete.c                 2	
X undelete.h                 1	
X util.c                     2	
X util.h                     1	
END_OF_FILE
if test 1261 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'PATCHLEVEL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'PATCHLEVEL'\"
else
echo shar: Extracting \"'PATCHLEVEL'\" \(3 characters\)
sed "s/^X//" >'PATCHLEVEL' <<'END_OF_FILE'
X17
END_OF_FILE
if test 3 -ne `wc -c <'PATCHLEVEL'`; then
    echo shar: \"'PATCHLEVEL'\" unpacked with wrong size!
fi
# end of 'PATCHLEVEL'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(4755 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X			       OVERVIEW
X
XThis archive contains the sources for five programs (well, actually,
Xfour, since one is a symbolic link):
X
X	delete
X	undelete
X	expunge
X	purge
X	lsdel
X
XThe programs were written at Project Athena in response to the problem
Xwhich many novice Unix users have with accidentally deleting files
Xthey didn't want to delete (Hell, I've done it :-).
X
X
X			 SUPPORTED PLATFORMS
X
XI've personally compiled these sources under Vax 4.3BSD, IBM AOS 4.3,
XMach on the NeXT Machine (with the "-bsd" flag to the compiler),
XUltrix 3.1 on the DECstation 3100, SunOS 4.0, A/UX, and HP-UX, and I
Xassume they should compile with minimal trouble on other
Xarchitectures.  If you make it compile on another platform and you
Xhave to make changes, please send me patches.
X
X
X			 WHAT YOU NEED TO DO
X
X1. Compile the com_err library (see below for more details) and
X   install it if you want to (you'll have to modify the delete
X   Makefile a bit if you don't).
X
X2. Edit the Makefile to fit your site.  See below for details.
X
X3. Compile away!  Type "make" to make without installing, or "make
X   install" to install binaries and man pages in the locations you
X   specified when you edited the Makefile.
X
X
X		       CUSTOMIZING THE MAKEFILE
X
XYou are probably going to have to do one or more of the following to
Xmake the Makefile work for you.
X
X1. Change the install binary directory and install man page directory
X   (and possibly man section).
X
X2. Change the ETINCS and ETLDFLAGS variables to point to the right
X   place.  Also, change the COMPILE_ET variable to point to a
X   compile_et executable if you haven't installed it somewhere in your
X   search path.
X
X3. If you want to be able to build dependencies, then change DEPEND to
X   the name of the program on your system that knows how to do that.
X
X4. If your system is SYSV-like (e.g. it uses strchr and strrchr
X   instead of index and rindex, or it has memcpy and doesn't have
X   bcopy), and your compile doesn't define the symbol SYSV
X   automatically, then put "-DSYSV" in the DEFINES variable.
X
X5. If you want to support Andrew File System (AFS) mountpoint
X   detection, and you have AFS include files and libraries available
X   to you, then uncomment the variables starting with "AFS" and set
X   them appropriately.
X
X6. See the comment in the Makefile about USE_BLOCKS.  If you do not
X   know whether or not you have st_blocks or if it represents 512-byte
X   blocks, run "make block-test" and you should be told what to do.
X
X
X			   COM_ERR LIBRARY
X
XIn order to compile delete, you need to get your hands on the com_err
Xpackage, which was written by members of the MIT Student Information
XProcessing Board (SIPB).  If com_err isn't available from the place
Xfrom which you got the delete sources, you can get it from volume 22
Xof the comp.sources.unix archives, under the name "et".  You should
Xcompile the library and compile_et utility that comes with it and then
Xeither install them in a "standard location" on your machine or modify
Xthe delete Makefile so that it knows where they are.  The delete
XMakefile does not compile them by default, since they are already
Xcompiled and installed at Athena, so you should compile and install
Xthem separately from delete.
X
X
X				 BUGS
X
XIt is not clear to me that the USE_BLOCKS code is going to do the
Xright thing on all systems.  If you define USE_BLOCKS and discover
Xthat lsdel, expunge or purge gives you bogus values for file sizes or
Xtotal amount of space, please let me know, because it will help me to
Xtighten up the code to work on a variety of different systems.
X
X
X		     I'M LOOKING FOR BETA-TESTERS
X
XI try to make this package run on as many different platforms as
Xpossible.  However, I do not have access to a large variety of
Xplatforms, so I can't effectively test all of the changes I make.  I'm
Xtherefore looking for people who are willing to beta-test changes
Xbefore I release them to the general public.  If you are interested in
Xdoing this, please let me know.
X
X
X			     ARCHIVE SITE
X
XThe most recent version of the delete package and patches to get from
Xprevious versions to the most recent version are archived on
Xpit-manager.mit.edu (18.72.1.58).  You can retrieve them via anonymous
Xftp in the directory /pub/delete, or via mail-server (send a message
Xwith the subject "help" to "mail-server@pit-manager.mit.edu").
X
X
X			     FINAL NOTES
X
XAs usual, suggestions and bug fixes are always welcomed.
X
XMy address:
X
XJonathan Kamens			              USnail:
XMIT Project Athena				11 Ashford Terrace
Xjik@Athena.MIT.EDU				Allston, MA  02134
XOffice: 617-253-8085			      Home: 617-782-0710
X
XP.S. Please see the file "mit-copying.h" for copying and
Xredistribution information.  Copyright 1991 Massachusetts Institute of
XTechnology.  All Rights Reserved.  Etc.
END_OF_FILE
if test 4755 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'block-test.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'block-test.c'\"
else
echo shar: Extracting \"'block-test.c'\" \(3264 characters\)
sed "s/^X//" >'block-test.c' <<'END_OF_FILE'
X/*
X * This program is a replacement for rm.  Instead of actually deleting
X * files, it marks them for deletion by prefixing them with a ".#"
X * prefix.
X *
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#if (!defined(lint) && !defined(SABER))
X     static char rcsid_block_test_c[] = "$Id: block-test.c,v 1.3 93/02/10 11:49:49 jik Exp $";
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/file.h>
X#include <stdio.h>
X#include "mit-copying.h"
X
Xmain()
X{
X     char filename[20];
X     int min_blocks, max_blocks, blocks, size, min_size, max_size;
X     
X     sprintf(filename, "test%d.out", getppid());
X
X     /* Find the mininum block size of a file */
X
X     min_blocks = write_file_blocks(filename, min_size = 1);
X
X     /* Now, find a file size that uses more blocks */
X
X     for (max_blocks = min_blocks, max_size = 1; max_blocks == min_blocks;
X	  max_size *= 2) {
X	  max_blocks = write_file_blocks(filename, max_size);
X     }
X
X     /* Now, search between them for the cutoff between min_blocks and */
X     /* (min_blocks + x) blocks					       */
X
X     while (1) {
X	  size = (max_size + min_size) / 2;
X	  if (write_file_blocks(filename, size) > min_blocks) {
X	       max_size = size;
X	       continue;
X	  }
X	  if (write_file_blocks(filename, size + 1) == min_blocks) {
X	       min_size = size;
X	       continue;
X	  }
X	  break;
X     }
X
X     /*
X      * At this point, the "size" variable contains the number of
X      * bytes in a physical block on the disk.  To make sure that the
X      * system isn't using some weird sort of adaptive block size
X      * system, we'll write twice that to the disk, and make sure that
X      * the resulting number of blocks agrees with 512-byte blocks.
X      */
X     size *= 2;
X     blocks = write_file_blocks(filename, size);
X     if (((size % 512) == 0) && (blocks == (size / 512))) {
X	  printf("You SHOULD define USE_BLOCKS.\n");
X     }
X     else {
X	  printf("You SHOULD NOT define USE_BLOCKS.\n");
X	  printf("However, you have an interesting machine that delete might be made to work\nbetter with.  Please contact the author (see the README file for an address)\nand tell him what kind of machine you have and what operating system it is\nrunning.\n");
X	  printf("Please tell him that a %d-byte file takes up %d blocks on your system.\n",
X		 size, blocks);
X     }
X     unlink(filename);
X     exit(0);
X}
X
X#ifndef MIN
X#define MIN(a,b) ((a)<(b)?(a):(b))
X#endif
X
Xwrite_file(filename, size)
Xchar *filename;
Xint size;
X{
X     int fd;
X     char buf[512];
X     int written;
X
X     if ((fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, 0644)) < 0) {
X	  perror(filename);
X	  exit(1);
X     }
X
X     while (size) {
X	  if ((written = write(fd, buf, MIN(size, sizeof(buf)))) < 0) {
X	       perror(filename);
X	       exit(1);
X	  }
X	  size -= written;
X     }
X
X     if (close(fd) < 0) {
X	  perror(filename);
X	  exit(1);
X     }
X}
X
Xfile_blocks(filename)
Xchar *filename;
X{
X     struct stat statbuf;
X
X     if (stat(filename, &statbuf) < 0) {
X	  perror(filename);
X	  exit(1);
X     }
X
X     return(statbuf.st_blocks);
X}
X
Xwrite_file_blocks(filename, size)
Xchar *filename;
X{
X     write_file(filename, size);
X     return(file_blocks(filename));
X}
END_OF_FILE
if test 3264 -ne `wc -c <'block-test.c'`; then
    echo shar: \"'block-test.c'\" unpacked with wrong size!
fi
# end of 'block-test.c'
fi
if test -f 'block-test.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'block-test.sh'\"
else
echo shar: Extracting \"'block-test.sh'\" \(377 characters\)
sed "s/^X//" >'block-test.sh' <<'END_OF_FILE'
XHOMEWD=`pwd`
Xcd ${TMPDIR-/tmp}
X
Xif ${CC-cc} -I${HOMEWD} -o test$$ ${HOMEWD}/block-test.c 2>&1 >/dev/null; then
X	if ./test$$; then : ;
X	else
X		echo "Test program did not succeed."
X		echo "This means you probably shouldn't define USE_BLOCKS."
X	fi
Xelse
X	echo "Could not compile test program."
X	echo "This means you probably shouldn't define USE_BLOCKS."
Xfi
X
X
Xrm -f test$$*
Xexit 0
END_OF_FILE
if test 377 -ne `wc -c <'block-test.sh'`; then
    echo shar: \"'block-test.sh'\" unpacked with wrong size!
fi
# end of 'block-test.sh'
fi
if test -f 'col.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'col.c'\"
else
echo shar: Extracting \"'col.c'\" \(5013 characters\)
sed "s/^X//" >'col.c' <<'END_OF_FILE'
X/*
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#if (!defined(lint) && !defined(SABER))
X     static char rcsid_col_c[] = "$Id: col.c,v 1.9 1992/11/10 05:57:24 jik Exp $";
X#endif
X
X/*
X * Note that this function has a lot of options I'm not really using
X * because I took it out of other code that needed a lot more
X * versatility.
X */
X
X#include <stdio.h>
X#ifdef SYSV
X#include <string.h>
X#define index strchr
X#define rindex strrchr
X#else
X#include <strings.h>
X#endif /* SYSV */
X#include "errors.h"
X#include "delete_errs.h"
X#include "col.h"
X#include "mit-copying.h"
X
X
Xstatic int calc_string_width(), calc_widths(), num_width();
Xstatic void trim_strings();
X
Xint column_array(strings, num_to_print, screen_width, column_width,
X		 number_of_columns, margin, spread_flag, 
X		 number_flag, var_col_flag, outfile)
Xchar **strings;
XFILE *outfile;
X{
X     char buf[BUFSIZ];
X     int updown, leftright, height;
X     int string_width;
X     int numwidth;
X
X     numwidth = num_width(num_to_print);
X     if (! var_col_flag) {
X	  string_width = calc_string_width(column_width, margin, number_flag,
X					   num_to_print);
X	  if (string_width <= 0) {
X	       set_error(COL_COLUMNS_TOO_THIN);
X	       error("calc_string_width");
X	       return error_code;
X	  }
X	  trim_strings(strings, num_to_print, string_width);
X     } else if (calc_widths(strings, &screen_width, &column_width,
X			    &number_of_columns, num_to_print, &margin,
X			    spread_flag, number_flag)) {
X	  error("calc_widths");
X	  return error_code;
X     }
X     height = num_to_print / number_of_columns;
X     if (num_to_print % number_of_columns)
X	  height++;
X     
X     if (number_flag) for (updown = 0; updown < height; updown++) {
X	  for (leftright = updown; leftright < num_to_print; ) {
X	       (void) sprintf(buf, "%*d. %s", numwidth, leftright+1,
X			      strings[leftright]);
X	       if ((leftright += height) >= num_to_print)
X		    fprintf(outfile, "%s", buf );
X	       else
X		    fprintf(outfile, "%*s", -column_width, buf);
X	  }
X	  fprintf(outfile, "\n");
X     } else for (updown = 0; updown < height; updown++) {
X	  for (leftright = updown; leftright < num_to_print; ) {
X	       (void) sprintf(buf, "%s", strings[leftright]);
X	       if ((leftright += height) >= num_to_print)
X		    fprintf(outfile, "%s", buf );
X	       else
X		    fprintf(outfile, "%*s", -column_width, buf);
X	  }
X	  fprintf(outfile, "\n");
X     }
X     return 0;
X}
X
Xstatic int calc_string_width(column_width, margin, number_flag, max_number)
X{
X     int string_width;
X     
X     string_width = column_width - margin;
X     if (number_flag)
X	  string_width = string_width - num_width(max_number) - strlen(". ");
X     return string_width;
X}
X
X
Xstatic void trim_strings(strings, number, width)
Xchar **strings;
X{
X     int loop;
X     
X     for (loop = 0; loop < number; loop++)
X	  if (strlen(strings[loop]) > width)
X	       strings[loop][width] = '\0';
X}
X
X
Xstatic int calc_widths(strings, screen_width, column_width, number_of_columns,
X		       num_to_print, margin, spread_flag, number_flag)
Xint *screen_width, *column_width, *number_of_columns, *margin;
Xchar **strings;
X{
X     int loop;
X     int maxlen, templen;
X     int spread;
X     
X     maxlen = templen = 0;
X     for (loop = 0; loop < num_to_print; loop++)
X	  if (maxlen < (templen = strlen(strings[loop])))
X	       maxlen = templen;
X
X     *column_width = maxlen;
X     
X     if (number_flag)
X	  *column_width = *column_width + num_width(num_to_print) +
X	       strlen(". ");
X
X     if (! spread_flag) {
X	  *column_width += *margin;
X	  if (! *number_of_columns) {
X	       *number_of_columns = *screen_width / *column_width;
X	       if (! *number_of_columns) {
X		    (*number_of_columns)++;
X		    *column_width -= *margin;
X		    *margin = 0;
X		    *screen_width = *column_width;
X	       }
X	  }
X	  else
X	       *screen_width = *number_of_columns * *column_width;
X     } else {
X	  if (! *number_of_columns) {
X	       *number_of_columns = *screen_width / (*column_width + *margin);
X	       if (! *number_of_columns) {
X		    (*number_of_columns)++;
X		    *screen_width = *column_width;
X		    *margin = 0;
X	       }
X	       spread = (*screen_width - *number_of_columns * *column_width)
X		    / *number_of_columns;
X	       *column_width += spread;
X	  }
X	  else {
X	       if (*number_of_columns * (*column_width + *margin) >
X		   *screen_width) {
X		    *column_width += *margin;
X		    *screen_width = *column_width;
X	       } else {
X		    spread = (*screen_width - (*number_of_columns *
X					       *column_width)) /
X						    *number_of_columns;
X		    *column_width += spread;
X	       }
X	  }
X     }
X     return 0;
X}
X
X
X	       
X
Xstatic int num_width(number)
Xint number;
X{
X     char buf[BUFSIZ];
X
X     (void) sprintf(buf, "%d", number);
X     return strlen(buf);
X}
END_OF_FILE
if test 5013 -ne `wc -c <'col.c'`; then
    echo shar: \"'col.c'\" unpacked with wrong size!
fi
# end of 'col.c'
fi
if test -f 'col.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'col.h'\"
else
echo shar: Extracting \"'col.h'\" \(1467 characters\)
sed "s/^X//" >'col.h' <<'END_OF_FILE'
X/*
X * $Id: col.h,v 1.4 1992/11/10 05:57:24 jik Exp $
X *
X * This header file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X/*
X * DEF_COL_WIDTH: the column with to try to use if none is specified.
X * DEF_WAIT: 1 if the program is supposed to wait for stdin to get to
X *           end-of-file and then print out everything in order in
X *           columns by default.  If this is 0, then the default is
X *           for the program to print across instead of down and to
X *           print as it receives input from stdin.
X * DEF_VAR_COLS: if 1, use variable-width columns based on text width.
X *               if 1, DEF_WAIT must be true.
X * DEF_SCR_WIDTH: default screen width
X * DEF_NUM_ITEMS: if 1, number each item
X * DEF_MARGIN: the default margin in between columns of text
X */ 
X#define DEF_COL_WIDTH 20
X#define DEF_WAIT 1
X#define DEF_VAR_COLS 1
X#define DEF_SCR_WIDTH 80
X#define DEF_NUM_ITEMS 1
X#define DEF_MARGIN 2
X /* This is used for when we need a guess as to how long a number will */
X /* be when printed.  Also, if we are supposed to work in wait mode    */
X /* and are not given a maxitems value, this is what is used.          */
X#define DEF_MAX_ITEMS 10000
END_OF_FILE
if test 1467 -ne `wc -c <'col.h'`; then
    echo shar: \"'col.h'\" unpacked with wrong size!
fi
# end of 'col.h'
fi
if test -f 'delete.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'delete.h'\"
else
echo shar: Extracting \"'delete.h'\" \(416 characters\)
sed "s/^X//" >'delete.h' <<'END_OF_FILE'
X/*
X * $Id: delete.h,v 1.6 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#include "mit-copying.h"
END_OF_FILE
if test 416 -ne `wc -c <'delete.h'`; then
    echo shar: \"'delete.h'\" unpacked with wrong size!
fi
# end of 'delete.h'
fi
if test -f 'delete_errs.et' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'delete_errs.et'\"
else
echo shar: Extracting \"'delete_errs.et'\" \(1400 characters\)
sed "s/^X//" >'delete_errs.et' <<'END_OF_FILE'
X#     Copyright 1988 Massachusetts Institute of Technology.
X#
X#     For copying and distribution information, see the file
X#     "mit-copying.h".
X#
X#     $Id: delete_errs.et,v 1.5 1992/11/10 05:57:24 jik Exp $
X#
X
X	et	del
X
Xec REGEXP_MISSING_QUOTED_CHAR,
X	"missing quoted character after backslash"
Xec REGEXP_MISSING_BRACE,
X	"missing ]"
Xec REGEXP_EMPTY_BRACES,
X	"illegal empty braces"
Xec DIR_NOT_DIRECTORY,
X	"internal error: directory operation on non-directory"
Xec DIR_IMPOSSIBLE_ERROR,
X	"interal error: something that shouldn't happen just did"
Xec COL_COLUMNS_TOO_THIN,
X	"possible internal error: listing columns too thin"
Xec DELETE_IS_DOTFILE,
X	"can't delete `.' or `..'"
Xec DELETE_CANT_DEL_DIR,
X	"can't delete (not file)"
Xec DELETE_DIR_NOT_EMPTY,
X	"can't delete (directory not empty)"
Xec DELETE_CANT_DEL_FILE,
X	"can't delete (not directory)"
Xec DELETE_NOT_DELETED,
X	""
Xec UNDEL_NOT_UNDELETED,
X	""
Xec NO_HOME_DIR,
X	"can't find home directory"
Xec INTERNAL_ERROR,
X	"strange internal error"
Xec ENOMATCH,
X	"no match"
Xec EXPUNGE_NOT_EXPUNGED,
X	""
Xec PURGE_TOO_MANY_ARGS,
X	"command takes no arguments"
Xec PAT_NO_FILES_REQUESTED,
X	"internal error: no files requested in call to find_matches or do_match"
Xec PAT_IS_MOUNT,
X	"ignored (is mount point)"
Xec STACK_BAD_OP,
X	"internal error: call to dostack with undefined stack operation"
Xec STACK_EMPTY,
X	"internal error: attempt to pop from empty stack"
X
X	end
X
END_OF_FILE
if test 1400 -ne `wc -c <'delete_errs.et'`; then
    echo shar: \"'delete_errs.et'\" unpacked with wrong size!
fi
# end of 'delete_errs.et'
fi
if test -f 'directories.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'directories.h'\"
else
echo shar: Extracting \"'directories.h'\" \(1870 characters\)
sed "s/^X//" >'directories.h' <<'END_OF_FILE'
X/*
X * $Id: directories.h,v 1.14 1993/10/13 13:52:50 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#include "mit-copying.h"
X
Xtypedef short Boolean;
X#define True			(Boolean) 1
X#define False			(Boolean) 0
X
X
X#ifdef USE_BLOCKS
X#define specs_to_space(x)	((x).st_blocks)
X#define space_to_k(x)		((x) / 2 + (((x) % 2) ? 1 : 0))
X#define specs_to_k(x)		space_to_k((x).st_blocks)
X#else
X#define specs_to_space(x)	((x).st_size)
X#define space_to_k(x)		((x) / 1024 + (((x) % 1024) ? 1 : 0))
X#define specs_to_k(x)		space_to_k((x).st_size)
X#endif
X
X#define FOLLOW_LINKS		1
X#define DONT_FOLLOW_LINKS	0
X
X#define DIR_MATCH		1
X#define DIR_NO_MATCH		0
X
Xtypedef struct mystat {
X     dev_t st_dev;
X     ino_t st_ino;
X     unsigned short st_mode;
X     off_t st_size;
X     time_t st_ctim;
X#ifdef USE_BLOCKS
X     long st_blocks;
X#endif
X} mystat;
X
X     
Xtypedef struct filrec {
X     char name[MAXNAMLEN];
X     struct filrec *previous;
X     struct filrec *parent;
X     struct filrec *dirs;
X     struct filrec *files;
X     struct filrec *next;
X     Boolean specified;
X     Boolean freed;
X     struct mystat specs;
X} filerec;
X
X
X
Xint add_directory_to_parent();
Xint add_file_to_parent();
Xint add_path_to_tree();
Xint find_child();
Xfilerec *first_in_directory();
Xfilerec *first_specified_in_directory();
Xfilerec *get_cwd_tree();
Xfilerec *get_root_tree();
Xfilerec *next_directory();
Xfilerec *next_in_directory();
Xfilerec *next_leaf();
Xfilerec *next_specified_directory();
Xfilerec *next_specified_in_directory();
Xfilerec *next_specified_leaf();
X
Xint get_leaf_path();
Xint accumulate_names();
X
Xvoid free_leaf();
END_OF_FILE
if test 1870 -ne `wc -c <'directories.h'`; then
    echo shar: \"'directories.h'\" unpacked with wrong size!
fi
# end of 'directories.h'
fi
if test -f 'errors.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'errors.c'\"
else
echo shar: Extracting \"'errors.c'\" \(1330 characters\)
sed "s/^X//" >'errors.c' <<'END_OF_FILE'
X/*
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#if (!defined(lint) && !defined(SABER))
X     static char rcsid_errors_c[] = "$Id: errors.c,v 1.5 1992/11/10 05:57:24 jik Exp $";
X#endif
X
X#include <com_err.h>
X#include <stdio.h>
X#include "delete_errs.h"
X#include "mit-copying.h"
X
Xchar *whoami;
Xint error_reported = 1;
Xint error_occurred = 0;
Xint report_errors = 1;
Xint error_code = 0;
X
X/*
X * Proper use of this procedure requires strict adherance to the way
X * it is supposed to be used by all procedures in a program.  Whenever
X * there is an error, set_error must be called with the error value.
X * Then, either the procedure that detects the error must call
X * error(), or it must pass the error up to its parent for the parent
X * to report.
X */
X
X
Xvoid error(str)
Xchar *str;
X{
X     if (report_errors && (! error_reported)) {
X	  if (*str)
X	       fprintf(stderr, "%s: %s: %s\n", whoami, str,
X		       error_message(error_code));
X	  else
X	       fprintf(stderr, "%s: %s\n", whoami, error_message(error_code));
X     }
X     error_reported = 1;
X}
END_OF_FILE
if test 1330 -ne `wc -c <'errors.c'`; then
    echo shar: \"'errors.c'\" unpacked with wrong size!
fi
# end of 'errors.c'
fi
if test -f 'errors.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'errors.h'\"
else
echo shar: Extracting \"'errors.h'\" \(742 characters\)
sed "s/^X//" >'errors.h' <<'END_OF_FILE'
X/*
X * $Id: errors.h,v 1.4 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
Xextern char *whoami;
Xextern int error_reported;
Xextern int error_occurred;
Xextern int report_errors;
Xextern int error_code;
X
Xvoid error();
X
X#define set_error(cd) {error_code = cd; error_reported = 0; error_occurred = 1;}
X#define set_warning(cd) {error_code = cd; error_reported = 0;}
X#define set_status(cd) {error_code = cd;}
END_OF_FILE
if test 742 -ne `wc -c <'errors.h'`; then
    echo shar: \"'errors.h'\" unpacked with wrong size!
fi
# end of 'errors.h'
fi
if test -f 'expunge.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expunge.h'\"
else
echo shar: Extracting \"'expunge.h'\" \(514 characters\)
sed "s/^X//" >'expunge.h' <<'END_OF_FILE'
X/*
X * $Id: expunge.h,v 1.6 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X#define ERROR_MASK		1
X#define NO_DELETE_MASK		2
X#define NO_TIMEOUT_MASK		4
X
Xint get_the_files();
END_OF_FILE
if test 514 -ne `wc -c <'expunge.h'`; then
    echo shar: \"'expunge.h'\" unpacked with wrong size!
fi
# end of 'expunge.h'
fi
if test -f 'lsdel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lsdel.h'\"
else
echo shar: Extracting \"'lsdel.h'\" \(483 characters\)
sed "s/^X//" >'lsdel.h' <<'END_OF_FILE'
X/*
X * $Id: lsdel.h,v 1.6 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X#define ERROR_MASK 1
X#define NO_DELETE_MASK 2
X
Xint get_the_files();
END_OF_FILE
if test 483 -ne `wc -c <'lsdel.h'`; then
    echo shar: \"'lsdel.h'\" unpacked with wrong size!
fi
# end of 'lsdel.h'
fi
if test -f 'malloc-test.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'malloc-test.c'\"
else
echo shar: Extracting \"'malloc-test.c'\" \(224 characters\)
sed "s/^X//" >'malloc-test.c' <<'END_OF_FILE'
Xmain()
X{
X     char *ptr1, *ptr2;
X
X     ptr1 = (char *) malloc(0);
X     ptr2 = (char *) realloc(ptr1, 0);
X
X     printf("You %s define MALLOC_0_RETURNS_NULL.\n",
X	    (ptr1 && ptr2) ? "should NOT" : "SHOULD");
X     exit(0);
X}
END_OF_FILE
if test 224 -ne `wc -c <'malloc-test.c'`; then
    echo shar: \"'malloc-test.c'\" unpacked with wrong size!
fi
# end of 'malloc-test.c'
fi
if test ! -d 'man1' ; then
    echo shar: Creating directory \"'man1'\"
    mkdir 'man1'
fi
if test -f 'man1/delete.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man1/delete.1'\"
else
echo shar: Extracting \"'man1/delete.1'\" \(4343 characters\)
sed "s/^X//" >'man1/delete.1' <<'END_OF_FILE'
X.\"	$Id: delete.1,v 1.7 1992/11/10 06:00:44 jik Exp $
X.\"
X.\" Copyright 1989 by the Massachusetts Institute of Technology.  All
X.\" rights reserved.  The file /usr/include/mit-copyright.h specifies
X.\" the terms and conditions for redistribution.
X.\"
X.\"
X.TH DELETE 1 "January 26, 1988" "MIT Project Athena"
X.ds ]W MIT Project Athena
X.SH NAME
Xdelete \- a recoverable file-deletion utility
X.SH SYNOPSIS
X.B delete
X[
X.B \-r
X] [
X.B \-i
X] [
X.B \-f
X] [
X.B \-n
X] [
X.B \-v
X] [
X.B \-e
X] [
X.B \-F
X] [
X.B \-D
X] [
X.B \-\|\-
X] filename ...
X.PP
X.SH DESCRIPTION
X.I Delete
Xmarks files and directories for later permanent removal (by renaming
Xthem with a prefix of \fI.#\fR).  Files accidentally marked for deletion
Xcan be recovered using
X.I undelete(1).
XMarked files are periodically
Xremoved automatically by the system; they can also be removed on demand
X(see \fIpurge\fR(1) and \fIexpunge\fR(1) for details).
XUsers can list files which have been marked for
Xremoval but have not yet been removed using \fIlsdel\fR(1).
X.PP
XIf the user does not have write permission to a file, its permissions
Xare printed and the user is asked whether the file should be removed.
XIf the first character of the response line is \fIy\fR the file is
Xremoved, otherwise it remains.
X.PP
XUsers wishing to retain the user interface of \fIrm\fR(1)
Xand \fIrmdir\fR(1)
Xwhile still being able to recover accidentally removed files can do so
Xby aliasing
X.I rm
Xto
X.I delete \-F \-e
Xand
X.I rmdir
Xto
X.I delete \-D \-e
X(see below).
X.SH OPTIONS
X.I Delete
Xaccepts the following command-line options:
X.TP
X.B \-r
XIf a designated filename is a non-empty directory,
X.I delete
Xwill signal an error unless the
X.B \-r
Xoption is specified.  In that case,
X.I delete
Xrecursively deletes the directory's entire contents and the directory
Xitself.  If the
X.B \-F
Xoption is specified (see below),
X.I delete
Xwill signal an error even if the directory is empty.
X.TP
X.B \-i
XCauses
X.I delete
Xto ask whether to delete each file, and, in recursive
Xmode, whether to examine each directory.
X.TP
X.B \-f
XPrevents
X.I delete
Xfrom asking any questions and from reporting any errors.
X.TP
X.B \-n
XNo file removals are performed.  Instead,
X.I delete
Xprints to the standard output the files that it would remove were the
X.B \-n
Xoption not specified.
X.TP
X.B \-v
XCauses
X.I delete
Xto report each file as it is deleted.
X.TP
X.B \-e
XCauses
X.I delete
Xto emulate \fIrm\fR(1) and \fIrmdir\fR(1) as much as it can (i.e.
Xerror and status messages and other peculiarities of \fIrm\fR(1) and
X\fIrmdir\fI(1)).
X.TP
X.B \-F
XCauses
X.I delete
Xto emulate
X.I rm
Xby preventing it from removing even empty directories when the
X.B \-r
Xoption is not specified.
X.TP
X.B \-D
XCauses
X.I delete
Xto emulate
X.I rmdir
Xby preventing it from removing anything but empty directories.
X.TP
X.B \-\|\-
XTwo dashes indicate that all the arguments following it are to be treated as
Xfile names, even if they start with a dash.
X.SH "SEE ALSO"
Xundelete(1), purge(1), expunge(1), lsdel(1), rm(1), rmdir(1)
X.SH BUGS
X.I Delete
Xmay change the access and modification times on a file when it is
Xdeleted.  This is necessary in order to guarantee that
X.I expunge
Xwill work correctly in
X.I AFS
Xfilesystems.  You might say that this is a bug in
X.IR AFS ,
Xrather than a bug in
X.IR delete .
X.SH AUTHOR
XJonathan I. Kamens (MIT-Project Athena)
X.SH COPYRIGHT
XCopyright (c) 1989 by the Massachusetts Institute of Technology.
X.PP
XAll rights reserved.
X.PP
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted,
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in
Xsupporting documentation, and that the name of the Massachusetts
XInstitute of Technology (M.I.T.) not be used in advertising or publicity
Xpertaining to distribution of the software without specific, written
Xprior permission.
X.PP
XM.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XM.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X
END_OF_FILE
if test 4343 -ne `wc -c <'man1/delete.1'`; then
    echo shar: \"'man1/delete.1'\" unpacked with wrong size!
fi
# end of 'man1/delete.1'
fi
if test -f 'man1/expunge.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man1/expunge.1'\"
else
echo shar: Extracting \"'man1/expunge.1'\" \(3903 characters\)
sed "s/^X//" >'man1/expunge.1' <<'END_OF_FILE'
X.\"	$Id: expunge.1,v 1.10 1992/11/10 06:00:44 jik Exp $
X.\"
X.\" Copyright 1989 by the Massachusetts Institute of Technology.  All
X.\" rights reserved.  The file /usr/include/mit-copyright.h specifies
X.\" the terms and conditions for redistribution.
X.\"
X.\"
X.TH EXPUNGE 1 "January 27, 1988" "MIT Project Athena"
X.ds ]W MIT Project Athena
X.SH NAME
Xexpunge, purge \- permanent removal of deleted files
X.SH SYNOPSIS
X.B expunge
X[
X.B \-r
X] [
X.B \-i
X] [
X.B \-f
X] [
X.B \-t \fIn\fR
X] [
X.B \-n
X] [
X.B \-v
X] [
X.B \-l
X] [
X.B \-s
X] [
X.B \-m
X] [
X.B \-y
X] [
X.B \-\|\-
X] [ filename [ ... ]]
X.PP
X.B purge
X.PP
X.SH DESCRIPTION
X.I Expunge
Xand
X.I purge
Xpermanently remove files which have been marked for deletion using
X\fIdelete\fR(1).  Files removed with \fIexpunge\fR or \fIpurge\fR
Xcannot be recovered, and care should therefore be exercised in the
Xuse of these utilities.
X.PP
X.I Purge
Xis a simple utility which takes no command-line arguments.  When it is
Xexecuted, it searches through the user's entire home directory and
Xfinds all files that have been marked for deletion.  It then displays
Xa list of the files where are to be removed and prompts for
Xconfirmation.  A response from the user starting with the letter
X\fIy\fR will cause the files to be permanently expunged.
X.PP
XBecause
X.I purge
Xsearches through the user's entire home directory, it can take quite a
Xwhile to complete its search.  This is normal.
X.PP
XThe filenames passed to
X.I expunge
Xon the command-line can be directories (deleted or not deleted) or
Xdeleted files.  Deleted files or directories are always completely
Xexpunged, while the treatment of non-deleted directories depends on
Xthe
X.BR \-r
Xcommand-line option (see below).  If no command-line filenames are
Xspecified,
X.I expunge
Xdefaults to the current working directory.
X.PP
XFor information about wildcard use with \fIexpunge\fR, please see
X\fIundelete\fR(1).
X.PP
X.SH OPTIONS
X.I Expunge
Xaccepts the following command-line options:
X.TP
X.B \-r
XWhen a non-deleted directory is passed to \fIexpunge\fR, the 
X.BR \-r
Xoption causes the directory to be searced recursively for deleted
Xfiles.  If the recursive option is \fInot\fR specified, only the
Xdirect children of the non-deleted directory are examined.  A
Xrecursive search of a large directory can take quite a while.
X.TP
X.B \-i
XThe user is prompted for confirmation with the name of the file and
Xits size in kilobytes before each file or directory is
Xremoved.
X.TP
X.B \-f
XUsed in conjunction with the
X.BR \-l
Xoption, this option prevents 
X.I expunge
Xfrom prompting for confirmation after listing all the files that are
Xto be deleted.  Furthermore, it prevents the printing of error
Xmessages.
X.TP
X.B \-t\fIn\fR
XSpecifies the minimum age (in days) of files to be expunged, measured
Xas the length of time since the file was
X.IR delete d.
X.TP
X.B \-n
XNo file expunges are performed.  Instead,
X.I expunge
Xprints to the standard output the files that it would expunge were the
X.BR \-n
Xoption not specified.
X.TP
X.B \-v
XCauses 
X.I expunge
Xto report each file as it is expunged, as well as the size of the file
Xand a running total of the number of kilobytes expunged.
X.TP
X.B \-l
XCauses 
X.I expunge
Xto list all found files before expunging them, similar to the actions
Xof
X.I purge.
X.TP
X.B \-s
XSymbolic links are followed when searching for deleted files.
X.TP
X.B \-m
XMount points are followed when searching for deleted files.
X.TP
X.B \-y
XThe total number of kilobytes expunged is printed after
X.I expunge
Xis finished removing files.
X.TP
X.B \-\|\-
XTwo dashes indicate that all arguments following it are to be treated
Xas file names, even if they start with a dash.
X.SH "SEE ALSO"
Xdelete(1), undelete(1), lsdel(1), rm(1), rmdir(1)
X.SH AUTHOR
XJonathan I. Kamens (MIT-Project Athena)
X.SH RESTRICTIONS
XCopyright (c) 1989 by the Massachusetts Institute of Technology.  All
Xrights reserved.
X.IR Delete (1)
Xspecifies the terms and conditions for redistribution.
END_OF_FILE
if test 3903 -ne `wc -c <'man1/expunge.1'`; then
    echo shar: \"'man1/expunge.1'\" unpacked with wrong size!
fi
# end of 'man1/expunge.1'
fi
if test -f 'man1/lsdel.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man1/lsdel.1'\"
else
echo shar: Extracting \"'man1/lsdel.1'\" \(2257 characters\)
sed "s/^X//" >'man1/lsdel.1' <<'END_OF_FILE'
X.\"	$Id: lsdel.1,v 1.8 1992/11/10 06:00:44 jik Exp $
X.\"
X.\" Copyright 1989 by the Massachusetts Institute of Technology.  All
X.\" rights reserved.  The file /usr/include/mit-copyright.h specifies
X.\" the terms and conditions for redistribution.
X.\"
X.\"
X.TH LSDEL 1 "January 27, 1988" "MIT Project Athena"
X.ds ]W MIT Project Athena
X.SH NAME
Xlsdel \- list deleted files
X.SH SYNOPSIS
X.B lsdel
X[
X.B \-d
X] [
X.B \-r
X] [
X.B \-t \fIn\fR
X] [
X.B \-s
X] [
X.B \-m
X] [
X.B \-y
X] [
X.B \-1
X] [
X.B \-C
X] [ filename [ ... ]]
X.PP
X.SH DESCRIPTION
X.I Lsdel
Xlists files that have been marked for deletion by the \fIdelete\fR(1)
Xprogram.
X.PP
XFor information about using wildcards with \fIlsdel\fR, see
X\fIundelete\fR(1).
X.PP
XFilenames passed to \fIlsdel\fR can be directories (non-deleted or
Xdeleted) or deleted files.  If a non-deleted directory is specified,
Xlsdel lists the deleted contents of that directory.  If the
X.BR \-r
Xoption is specified, all non-deleted children of the directory will be
Xsearched recursively for deleted files.  If no command-line filenames
Xare specified,
X.I lsdel
Xdefaults to the current working directory.
X.PP
X.I Lsdel
Xrecursively lists deleted directories by default.  This can be
Xdisabled with the
X.BR \-d
Xoption, which causes directory names, rather than their contents, to
Xbe listed.
X.PP
XThe
X.BR \-t
Xoption allows the user to specify a minimum age, in days, of files to
Xlist.  Only files that were
X.IR delete d
X\fIn\fR days or more ago will be listed.
X.PP
XThe
X.BR \-s
Xoptions tells
X.I lsdel
Xto follow symbolic links when searching for deleted files.  The
X.BR \-m
Xoption does the same thing for mount points.
X.PP
XThe
X.BR \-y
Xoption causes
X.I lsdel
Xto print the total amount of space taken up by all the files it lists.
X.PP
XThe
X.BR \-1
Xoption forces output to be one file per line; this is the default when
Xoutput is not to a terminal.  The
X.BR \-C
Xoption does the opposite, forcing multi-column output, which is the
Xdefault when output is to a terminal.
X.SH "SEE ALSO"
Xdelete(1), undelete(1), purge(1), expunge(1), ls(1)
X.SH AUTHOR
XJonathan I. Kamens (MIT-Project Athena)
X.SH RESTRICTIONS
XCopyright (c) 1989 by the Massachusetts Institute of Technology.  All
Xrights reserved.
X.IR Delete (1)
Xspecifies the terms and conditions for redistribution.
END_OF_FILE
if test 2257 -ne `wc -c <'man1/lsdel.1'`; then
    echo shar: \"'man1/lsdel.1'\" unpacked with wrong size!
fi
# end of 'man1/lsdel.1'
fi
if test -f 'man1/purge.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man1/purge.1'\"
else
echo shar: Extracting \"'man1/purge.1'\" \(273 characters\)
sed "s/^X//" >'man1/purge.1' <<'END_OF_FILE'
X.\"	$Id: purge.1,v 1.2 1992/11/10 06:00:44 jik Exp $
X.\"
X.\" Copyright 1989 by the Massachusetts Institute of Technology.  All
X.\" rights reserved.  The file /usr/include/mit-copyright.h specifies
X.\" the terms and conditions for redistribution.
X.\"
X.\"
X.so man1/expunge.1
END_OF_FILE
if test 273 -ne `wc -c <'man1/purge.1'`; then
    echo shar: \"'man1/purge.1'\" unpacked with wrong size!
fi
# end of 'man1/purge.1'
fi
if test -f 'man1/undelete.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man1/undelete.1'\"
else
echo shar: Extracting \"'man1/undelete.1'\" \(3355 characters\)
sed "s/^X//" >'man1/undelete.1' <<'END_OF_FILE'
X.\"	$Id: undelete.1,v 1.6 1992/11/10 06:00:44 jik Exp $
X.\" Copyright 1989 by the Massachusetts Institute of Technology.  All
X.\" rights reserved.  The file /usr/include/mit-copyright.h specifies
X.\" the terms and conditions for redistribution.
X.\"
X.\"
X.TH UNDELETE 1 "January 26, 1988" "MIT Project Athena"
X.ds ]W MIT Project Athena
X.SH NAME
Xundelete \- recover files removed by delete
X.SH SYNOPSIS
X.B undelete
X[
X.B \-r
X] [
X.B \-i
X] [
X.B \-f
X] [
X.B \-v
X] [
X.B \-n
X] [
X.B \-R
X] [
X.B \-\|\-
X] [ filename [ ... ]]
X.PP
X.DESCRIPTION
X.I Undelete
Xrecovers files and directories that have been marked for permanent removal by 
X\fIdelete\fR(1), but have not
Xyet been removed.
X.PP
XFilenames passed to
X.I undelete
Xcan be directories or deleted files.
XIf a directory that is not deleted is passed to
X.I undelete,
Xthen the deleted files or directories in it will be restored; if the
Xrecursive option is specified, then all deleted files or directories
Xin any of its children will be restored as well.
X.PP
XThe shell wildcards \fI*\fR and \fI?\fR, as well as shell brace
Xnotation using \fI[\fR and \fI]\fR, are interpreted correctly by
X.I undelete.
XIt is possible to pass wildcards to the program without the wildcards
Xbeing intercepted by the shell by setting
X.I noglob
X(in \fIcsh\fR) or by quoting the wildcards.  To delete a file that
Xactually has a wildcard in its name, you must precede the quoted
Xwildcard with a quoted backslash.
X.PP
XIf no files are specified on the command line,
X.I undelete
Xgoes into interactive mode.  In interactive mode, the user is prompted
Xto enter files to be restored, one file per line.  Typing a carriage
Xreturn on an empty prompt line exits the program.
X.PP
XWildcards and quoting backslashes can be entered directly at the
Xprompt without any shell interference (which is the
Xmain reason there is an interactive mode).
X.SH OPTIONS
X.I Undelete
Xaccepts the following command-line options:
X.TP
X.B \-r
XIf a specified file is a directory, the directory and all of its
Xchildren are restored recursively.
X.TP
X.B \-i
XThe user is prompted for confirmation before each file or directory is
Xrestored.  This is not the same as the interactive file name entry
Xmode which is automatically activated when no files are specified on
Xthe command line.
X.TP
X.B \-f
XPrevents
X.I undelete
Xfrom reporting errors.  Further, if an intact (undeleted) version of a
Xfile which is requested for undeletion exists, then
X.I undelete
Xwill not prompt for confirmation before overwriting the undeleted file
Xwith the recovered one.
X.TP
X.B \-v
XCauses
X.I undelete
Xto report each file as it is restored.  Also, causes an introductory
Xmessage to be printed when entering interactive mode.
X.TP
X.B \-n
XNo file recoveries are performed.  Instead,
X.I undelete
Xprints to the standard output the files that it would recover were the
X.B \-n
Xoption not specified.
X.TP
X.B \-R
XPrevents
X.I undelete
Xfrom restoring the contents of directories in any case.
X.TP
X.B \-\|\-
XTwo dashes indicate that all arguments following it are to be treated as file
Xnames, even if they start with a dash.
X.SH "SEE ALSO"
Xdelete(1), purge(1), expunge(1), lsdel(1), rm(1), rmdir(1)
X.SH AUTHOR
XJonathan I. Kamens (MIT-Project Athena)
X.SH RESTRICTIONS
XCopyright (c) 1989 by the Massachusetts Institute of Technology.  All
Xrights reserved.
X.IR Delete (1)
Xspecifies the terms and conditions for redistribution.
END_OF_FILE
if test 3355 -ne `wc -c <'man1/undelete.1'`; then
    echo shar: \"'man1/undelete.1'\" unpacked with wrong size!
fi
# end of 'man1/undelete.1'
fi
if test -f 'mit-copying.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mit-copying.h'\"
else
echo shar: Extracting \"'mit-copying.h'\" \(1030 characters\)
sed "s/^X//" >'mit-copying.h' <<'END_OF_FILE'
X/*
X
XCopyright 1987,1988,1991 by the Massachusetts Institute of Technology
X
XAll rights reserved.
X
XPermission to use, copy, modify, and distribute this software and its
Xdocumentation for any purpose and without fee is hereby granted,
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in
Xsupporting documentation, and that the name of the Massachusetts
XInstitute of Technology (M.I.T.) not be used in advertising or publicity
Xpertaining to distribution of the software without specific, written
Xprior permission.
X
XM.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XM.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X*/
END_OF_FILE
if test 1030 -ne `wc -c <'mit-copying.h'`; then
    echo shar: \"'mit-copying.h'\" unpacked with wrong size!
fi
# end of 'mit-copying.h'
fi
if test -f 'pattern.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pattern.h'\"
else
echo shar: Extracting \"'pattern.h'\" \(1057 characters\)
sed "s/^X//" >'pattern.h' <<'END_OF_FILE'
X/*
X * $Id: pattern.h,v 1.7 1992/11/10 05:57:24 jik Exp $
X * 
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
Xint add_str();
Xint add_arrays();
Xint find_contents();
Xint find_deleted_contents();
Xint find_deleted_contents_recurs();
Xint find_matches();
Xint find_deleted_matches();
Xint find_recurses();
Xint find_deleted_recurses();
X
X#define FIND_DELETED		(1<<0)
X#define FIND_UNDELETED		(1<<1)
X#define RECURS_FIND_DELETED	(1<<2)
X#define RECURS_FIND_UNDELETED	(1<<3)
X#define RECURS_DELETED		(1<<4)
X#define FOLLW_LINKS		(1<<5)
X#define FOLLW_MOUNTPOINTS	(1<<6)
X#define FIND_DOTFILES		(1<<7)
X#define FIND_CONTENTS		(1<<8)
X#define SUPPRESS_WARNINGS	(1<<9)
X#define RECURS			(RECURS_FIND_DELETED | RECURS_FIND_UNDELETED |\
X				 RECURS_DELETED | FIND_CONTENTS)
END_OF_FILE
if test 1057 -ne `wc -c <'pattern.h'`; then
    echo shar: \"'pattern.h'\" unpacked with wrong size!
fi
# end of 'pattern.h'
fi
if test -f 'shell_regexp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'shell_regexp.c'\"
else
echo shar: Extracting \"'shell_regexp.c'\" \(3039 characters\)
sed "s/^X//" >'shell_regexp.c' <<'END_OF_FILE'
X/*
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#if (!defined(lint) && !defined(SABER))
X     static char rcsid_shell_regexp_c[] = "$Id: shell_regexp.c,v 1.4 1992/11/10 05:57:24 jik Exp $";
X#endif
X
X#include <com_err.h>
X#include "shell_regexp.h"
X#include "delete_errs.h"
X#include "errors.h"
X#include "mit-copying.h"
X
Xstatic int real_cmp();
X
X/*
X * This is a simple pattern matcher that takes a pattern string and
X * another string (theoretically a filename) and checks if the second
X * string matches the pattern string using shell special characters
X * (i.e. it recognizes \, ?, *, [, ]).  It also special cases dot
X * files (i.e. * doesn't match files that start with periods, and
X * neither will ?*, and neither will [.]*).
X */
X
Xint reg_cmp(pattern, filename)
Xchar *pattern, *filename;
X{
X     /* First, dot file special cases */
X     if ((*filename == '.') && (*pattern != '.'))
X	  return REGEXP_NO_MATCH;
X
X     return real_cmp(pattern, filename);
X}
X
Xstatic int real_cmp(pattern, filename)
Xchar *pattern, *filename;
X{
X     if (*pattern == '\0') {
X	  if (*filename == '\0')
X	       return REGEXP_MATCH;
X	  else
X	       return REGEXP_NO_MATCH;
X     }
X     
X     if (*pattern == '*') {
X	  int retval;
X	  char *ptr;
X	  
X	  if (*(pattern + 1) == '\0')
X	       /* asterisk by itself matches anything */
X	       return REGEXP_MATCH;
X	  for (ptr = filename; *ptr; ptr++)
X	       if ((retval = real_cmp(pattern + 1, ptr)) != REGEXP_NO_MATCH)
X		    return retval;
X	  return REGEXP_NO_MATCH;
X     }
X
X     if (*filename == '\0')
X	  return REGEXP_NO_MATCH;
X     
X     if (*pattern == '?')
X	  return real_cmp(pattern + 1, filename + 1);
X
X     if (*pattern == '\\') {
X	  if (*(pattern + 1) == '\0') {
X	       set_error(REGEXP_MISSING_QUOTED_CHAR);
X	       return -1;
X	  }
X	  if (*(pattern + 1) == *filename)
X	       return real_cmp(pattern + 2, filename + 1);
X	  else
X	       return REGEXP_NO_MATCH;
X     }
X
X     if (*pattern == '[') {
X	  char *ptr, *end_ptr;
X
X	  for (end_ptr = pattern + 1; (*end_ptr != '\0') && (*end_ptr != ']');
X	       end_ptr++) ;
X	  if (*end_ptr == '\0') {
X	       set_error(REGEXP_MISSING_BRACE);
X	       return -1;
X	  }
X	  if (end_ptr == pattern + 1) {
X	       set_error(REGEXP_EMPTY_BRACES);
X	       return -1;
X	  }
X	  for (ptr = pattern + 1; ptr < end_ptr; ptr++) {
X	       if ((*(ptr + 1) == '-') && (*(ptr + 2) != ']')) {
X		    if ((*ptr <= *filename) && (*(ptr + 2) >= *filename))
X			 return real_cmp(end_ptr + 1, filename + 1);
X		    else {
X			 ptr += 2;
X			 continue;
X		    }
X	       }
X	       if (*ptr == *filename)
X		    return real_cmp(end_ptr + 1, filename + 1);
X	  }
X
X	  return REGEXP_NO_MATCH;
X     }
X		    
X     if (*pattern == *filename)
X	  return real_cmp(pattern + 1, filename + 1);
X     else
X	  return REGEXP_NO_MATCH;
X}
END_OF_FILE
if test 3039 -ne `wc -c <'shell_regexp.c'`; then
    echo shar: \"'shell_regexp.c'\" unpacked with wrong size!
fi
# end of 'shell_regexp.c'
fi
if test -f 'shell_regexp.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'shell_regexp.h'\"
else
echo shar: Extracting \"'shell_regexp.h'\" \(496 characters\)
sed "s/^X//" >'shell_regexp.h' <<'END_OF_FILE'
X/*
X * $Id: shell_regexp.h,v 1.4 1992/11/10 05:57:24 jik Exp $
X *
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
Xextern int reg_cmp();
X
X#define REGEXP_MATCH 1
X#define REGEXP_NO_MATCH 0
END_OF_FILE
if test 496 -ne `wc -c <'shell_regexp.h'`; then
    echo shar: \"'shell_regexp.h'\" unpacked with wrong size!
fi
# end of 'shell_regexp.h'
fi
if test -f 'stack.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stack.c'\"
else
echo shar: Extracting \"'stack.c'\" \(3694 characters\)
sed "s/^X//" >'stack.c' <<'END_OF_FILE'
X/*
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X
X#if (!defined(lint) && !defined(SABER))
X     static char rcsid_stack_c[] = "$Id: stack.c,v 1.11 1992/11/10 05:57:24 jik Exp $";
X#endif
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <errno.h>
X#include "stack.h"
X#include "delete_errs.h"
X#include "errors.h"
X#include "mit-copying.h"
X#include "util.h"
X
Xextern char *realloc();
Xextern int errno;
X
X#define STACK_INC 	25
X
X
X
Xint dostack(data, op, bytes)
Xcaddr_t data;
Xint op, bytes;
X{
X     static caddr_t stack = (caddr_t) NULL;
X     static int size = 0, count = 0;
X     
X     switch (op) {
X     case EMPTY_STACK:
X	  if (size) {
X	       free(stack);
X	       stack = (caddr_t) NULL;
X	       size = count = 0;
X	  }
X#ifdef STACK_DEBUG
X	  fprintf(stderr, "dostack: return 1 (EMPTY_STACK).\n");
X#endif
X	  return 0;
X     case STACK_PUSH:
X	  if (bytes == 0) {
X#ifdef STACK_DEBUG
X	       fprintf(stderr, "Pushing 0 bytes at %d offset.\n", count);
X	       fprintf(stderr, "dostack: return 2 (STACK_PUSH).\n");
X#endif
X	       return 0;
X	  }
X	  if (size - count < bytes) {
X	       do
X		    size += STACK_INC;
X	       while (size - count < bytes);
X	       stack = (caddr_t) (stack ? realloc((char *) stack,
X						  (unsigned) size) :
X				  Malloc((unsigned) size));
X#ifdef MALLOC_0_RETURNS_NULL
X	       if ((! stack) && size)
X#else
X	       if (! stack)
X#endif
X	       {
X		    size = count = 0;
X		    set_error(errno);
X		    error("Malloc");
X#ifdef STACK_DEBUG
X		    fprintf(stderr, "dostack: return 3 (STACK_PUSH).\n");
X#endif
X		    return error_code;
X	       }
X	  }
X#ifdef STACK_DEBUG
X	  fprintf(stderr, "Pushing %d bytes at %d offset.\n", bytes, count);
X#endif
X#if defined(SYSV) || (defined(__STDC__) && !defined(__HIGHC__))
X	  memcpy(stack + count, data, bytes);
X#else
X	  bcopy(data, stack + count, bytes);
X#endif
X	  count += bytes;
X#ifdef STACK_DEBUG
X	  fprintf(stderr, "dostack: return 4 (STACK_PUSH).\n");
X#endif
X	  return 0;
X     case STACK_POP:
X	  if (bytes == 0) {
X#ifdef STACK_DEBUG
X	       fprintf(stderr, "Popping 0 bytes at %d offset.\n", count);
X	       fprintf(stderr, "dostack: return 5 (STACK_POP).\n");
X#endif
X	       return 0;
X	  }
X	  if (count == 0) {
X	       set_status(STACK_EMPTY);
X#ifdef STACK_DEBUG
X	       fprintf(stderr, "dostack: return 6 (STACK_POP).\n");
X#endif
X	       return error_code;
X	  }
X	  else {
X	       int newblocks, newsize;
X
X	       count -= bytes;
X#ifdef STACK_DEBUG
X	       fprintf(stderr, "Popping %d bytes at %d offset.\n", bytes,
X		       count);
X#endif
X#if defined(SYSV) || (defined(__STDC__) && !defined(__HIGHC__))
X	       memcpy(data, stack + count, bytes);
X#else
X	       bcopy(stack + count, data, bytes);
X#endif
X	       newblocks = count / STACK_INC + ((count % STACK_INC) ? 1 : 0);
X	       newsize = newblocks * STACK_INC;
X	       if (newsize < size) {
X		    size = newsize;
X		    stack = (caddr_t) realloc((char *) stack, (unsigned) size);
X#ifdef MALLOC_0_RETURNS_NULL
X		    if ((! stack) && size)
X#else
X		    if (! stack)
X#endif
X	            {
X			 set_error(errno);
X			 error("realloc");
X#ifdef STACK_DEBUG
X			 fprintf(stderr, "dostack: return 7 (STACK_POP).\n");
X#endif
X			 return error_code;
X		    }
X	       }
X#ifdef STACK_DEBUG
X	       fprintf(stderr, "dostack: return 8 (STACK_POP).\n");
X#endif
X	       return 0;
X	  }
X     default:
X	  set_error(STACK_BAD_OP);
X#ifdef STACK_DEBUG
X	  fprintf(stderr, "dostack: return 9.\n");
X#endif
X	  return error_code;
X     }
X}
END_OF_FILE
if test 3694 -ne `wc -c <'stack.c'`; then
    echo shar: \"'stack.c'\" unpacked with wrong size!
fi
# end of 'stack.c'
fi
if test -f 'stack.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stack.h'\"
else
echo shar: Extracting \"'stack.h'\" \(677 characters\)
sed "s/^X//" >'stack.h' <<'END_OF_FILE'
X/*
X * $Id: stack.h,v 1.4 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X#define STACK_PUSH 	0
X#define STACK_POP	1
X#define EMPTY_STACK	2
X
X#define push(data, size)	dostack((caddr_t) data, STACK_PUSH, size)
X#define pop(data, size)		dostack((caddr_t) data, STACK_POP, size)
X#define popall()		dostack((caddr_t) NULL, EMPTY_STACK, 0)
X     
END_OF_FILE
if test 677 -ne `wc -c <'stack.h'`; then
    echo shar: \"'stack.h'\" unpacked with wrong size!
fi
# end of 'stack.h'
fi
if test -f 'undelete.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'undelete.h'\"
else
echo shar: Extracting \"'undelete.h'\" \(605 characters\)
sed "s/^X//" >'undelete.h' <<'END_OF_FILE'
X/*
X * $Id: undelete.h,v 1.6 1992/11/10 05:57:24 jik Exp $
X * 
X * This program is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X#define DELETEPREFIX ".#"
X#define DELETEREPREFIX "\\.#"
X
Xtypedef struct {
X     char *user_name;
X     char *real_name;
X} listrec;
X
Xint sort_files();
Xint unique();
X
Xint get_the_files();
END_OF_FILE
if test 605 -ne `wc -c <'undelete.h'`; then
    echo shar: \"'undelete.h'\" unpacked with wrong size!
fi
# end of 'undelete.h'
fi
if test -f 'util.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util.h'\"
else
echo shar: Extracting \"'util.h'\" \(1075 characters\)
sed "s/^X//" >'util.h' <<'END_OF_FILE'
X/*
X * $Id: util.h,v 1.13 1992/11/10 05:57:24 jik Exp $
X * 
X * This file is part of a package including delete, undelete,
X * lsdel, expunge and purge.  The software suite is meant as a
X * replacement for rm which allows for file recovery.
X * 
X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
X * For copying and distribution information, see the file "mit-copying.h."
X */
X#include "mit-copying.h"
X
X#include <sys/stat.h>
X#ifndef S_IFLNK
X#define lstat stat
X#endif
X
Xchar *append();
Xchar *convert_to_user_name();
Xchar *firstpart();
Xchar *lastpart();
Xchar *strindex();
Xchar *strrindex();
X#ifdef MALLOC_DEBUG
Xchar *Malloc();
X#else
X#define Malloc(a) malloc(a)
Xextern char *malloc();
X#endif
X
Xint is_mountpoint(), is_link();
X
X#define is_dotfile(A) ((*A == '.') && \
X		       ((*(A + 1) == '\0') || \
X			((*(A + 1) == '.') && \
X			 (*(A + 2) == '\0'))))
X
X#define is_deleted(A) ((*A == '.') && (*(A + 1) == '#'))
X
X /* It would be BAD to pass something with a ++ anywhere near it into */
X /* this macro! 						      */
X#define Opendir(dir) opendir(*(dir) ? (dir) : ".")
END_OF_FILE
if test 1075 -ne `wc -c <'util.h'`; then
    echo shar: \"'util.h'\" unpacked with wrong size!
fi
# end of 'util.h'
fi
echo shar: End of archive 1 \(of 4\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
