Making rm undoable

Dan Bernstein bernsten at phoenix.Princeton.EDU
Sat Mar 4 00:40:30 AEST 1989


The lack of protection against completely unlinking UNIX files, methods
of setting up a ``trash can,'' etc., are frequent subjects of discussion
here. Consider the following idea: If every file has an extra link in a
special directory meant only for such links, then one doesn't even need
to change how rm works in order to preserve files; removing a file or
moving another on top of it will not destroy it.

To be more specific, in your home directory have a .Copies directory,
inaccessible except at select times. In .Copies are files COPY000000,
COPY000001, etc., and a file, linklist, that maps each copy number
to one or more pathnames. Every COPY file is originally a hard link to
a file outside .Copies; if a COPY file has only a single link, the
original must have been deleted.

The ``emptytrash'' command thus finds and unlink any COPY file with
a single link. ``setuptrash'' recursively finds all files within your
home directory (except in .Copies) and links each to a COPY file,
checking inode numbers to determine whether it's repeating itself.
``unrm'' will probably be the most difficult command to write, because
even if each of the above makes a valiant effort to maintain the linklist,
/bin/mv and the rename() call don't. Intelligently finding the correct
file could be quite a chore when someone just says ``unrm core.'' But
simply assuming that ``core'' means the current working directory slash
core would be good enough for most cases.

It is hoped that the extra links themselves within .Copies do not take
up enough file space that they must be removed often, for setuptrash is
naturally continuous from the previous setuptrash, doing no extra ln's.
(It would be dangerous to have two links within .Copies to the same
file, for then that file will never be removed automatically; it is
perhaps worth an extra program to check for this.) setuptrash doesn't
really need to be done in the foreground, so even with large directories
the user need not perceive the delay. emptytrash needs only search a
single (though humungous) directory, so it could probably be done in
every .logout.

Dealing with files moving around and directories moving around makes
automatic unrm operation more difficult, unless mv and mvdir are
rewritten to maintain linklist. If setuptrash were running continuously
this would not be a problem, but more realistically, it is for unrm to
figure out which file you mean and give you a choice if necessary.

A more serious problem is that a new file created after the latest
setuptrash (e.g., during a session if setuptrash is run by .login)
will not be preserved. It seems to me that this is just something to
warn the user about---that new files are considered in some sense
temporary until you run setuptrash.

Note that setting this up would change the perceived behavior of rm
slightly: at least on this system, rm asks for confirmation if the file
has any strange bits set, but only if the file has exactly one link left.
With all the .Copies COPY files running around, rm would never ask for
this confirmation. (Which makes sense as it's so easy to unrm.)

Mail me any corrections, questions, comments, or implementations. I will
post a summary in a week.

---Dan Bernstein, bernsten at phoenix.princeton.edu



More information about the Comp.unix.wizards mailing list