File: README

package info (click to toggle)
libtrash 2.4-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 372 kB
  • ctags: 140
  • sloc: ansic: 1,910; perl: 346; makefile: 82
file content (443 lines) | stat: -rw-r--r-- 17,644 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
libtrash - a shared library which implements an intelligent, highly configurable
--------   "recycle bin" or "trash can" under GNU/Linux.


Written by Manuel Arriaga (manuelarriaga@gmail.com).

Copyright (C) 2001, 2002, 2003, 2004, 2005 Manuel Arriaga
Licensed under the GNU General Public License version 2.  See the file 
COPYING for details.


Version: 2.4 (2005/Sep/24)
-------


DESCRIPTION: 
-----------

libtrash is a shared library which, when preloaded, will intercept
calls to a series of GNU libc functions and make sure that, if an
attempt to destroy certain files is made, these won't be permanently
destroyed but rather moved to a "trash can".  It also allows the user
to mark certain directories as "unremovable", which means that calls
to functions which would result in the loss of files under these
directories will always fail, leaving those files untouched in their
original locations.

(This last feature is meant as a higher-level substitute for ext2fs'
"immutable" flag for use by those of us who rely on other file
systems. An important difference is that libtrash allows
non-privileged users to use this with their personal files.)

The GNU libc functions which can be overriden/"wrapped" are

- unlink();
- rename();
- fopen() / fopen64();
- freopen() / freopen64();
- open() / open64().

You can individually enable / disable each of these "protections"; by
default, only calls to the first two functions are intercepted.

----------------------------------------------------------------------------

IMPORTANT NOTE 1: The wrappers of the "open functions" (fopen, freopen
and open) behave differently from the real functions in an important
way when they are asked to open - in either write-mode or
read-plus-write-mode - a file considered "worthy" of having a copy of
itself stored in the trash can before being truncated: while the
functions in GNU libc require write-permission to that already
existing file for the call to succeed, these wrappers require
write-permission to the DIRECTORY WHICH HOLDS THAT FILE instead. This
is so because, in fact, we are renaming the existing file before
opening it, and calls to rename() require write-permission to the
directory which holds the file for them to succeed. Usually, you only
have write-permission to files in directories to which you also have
write-permission, so this shouldn't be a huge problem in most cases.

IMPORTANT NOTE 2: When a file on a partition / filesystem other than
the one in which your trash can resides is destroyed, libtrash can't
just use the GNU libc function rename() to move it into your trash
can: it must copy that file byte-after-byte into your trash can and
then delete the original. To achieve that, read-permission to the
destroyed file is required. Since in most situations you don't have
write-permission to a directory which holds files you can't read,
hopefully that won't prove a big problem, either. However, be warned
that copying a file (especially a large one) will take a lot longer
than the time which would be required to simply rename it.

----------------------------------------------------------------------------


libtrash works with any GNU/Linux program, both at the console and
under XFree86, and operates independently of the programming language
the program was written in. The only exception are statically linked
programs, which you probably won't find. It can be extensively
configured by each user through a personal, user-specific
configuration file.

Although libtrash itself was written in C, the installation procedure
requires Perl.


HOW libtrash WORKS / FEATURES:
-----------------------------

libtrash recreates the directory structure of your home directory under the
trash can, which means that, should you need to recover the mistakenly
deleted file /home/user/programming/test.c, it will be stored in
/home/user/Trash/programming/test.c. If you have instructed libtrash to also
store copies of files which you delete in directories outside of your home
dir (see libtrash.conf for details), they will be available under
Trash/SYSTEM_ROOT. E.g.: after deletion by the user joe, /common-dir/doc.txt
will be available at /home/joe/Trash/SYSTEM_ROOT/common-dir/doc.txt.


When you try to delete a file in a certain directory where you had
previously deleted another file with the same name, libtrash stores the new
file with a different name, in order to preserve both files. E.g.:

$ touch test
$ rm test
$ ls Trash/
test
$ touch test
$ rm test
$ ls Trash/
test test[1]    <-- The file we deleted first wasn't lost.

libtrash keeps generating new names until no name collision occurs. The
deletion of a file never causes the permanent loss of a previously "deleted"
file.


Temporary files can be automatically "ignored" and really destroyed.


You can define whether you wish to allow the definitive removal of files
already in your trash can while libtrash is active. Allowing this has one
major disadvantage, which is explained in libtrash.conf. But, on the other
hand, if you don't allow the destruction of files already in your trash can,
when you need to recover HD space by permanently removing files currently
found in your trash can you will have to temporarily disable libtrash first
(instructions on how to achieve this can be found below). 

To avoid the accumulation of useless files in your users' trash cans, it is
probably wise to run the script cleanTrash regularly (perhaps from a cron
job). This Perl script was kindly provided by Daniel Sadilek and works by
removing the oldest files from each trash can in your system whenever that
trash can grows beyond a certain disk size. It is meant to be run by root. 
cleanTrash, together with the license according to which it can be
distributed and a short README file written by me, can be found under the
directory "cleanTrash".


You can also choose whether files outside of your home directory, hidden
files (and files under hidden directories), backup and temporary files used
by text editors and files on removable media should be handled normally or
"ignored" (i.e., you can decide if copies of such files should be created in
your trash can if the originals are about to be destroyed). It is also
possible to discriminate files based on their names' extensions: you can
instruct libtrash, e.g., to always ignore object files (files with the
extension ".o"), meaning that deleting files of this type won't result in
the creation of copies of these in your trash can. By default, besides
object files, TeX log and auxiliary files (".log" and ".aux", respectively)
are also ignored.


The user may also configure libtrash to print a warning message to
stderr after each "dangerous" function call while libtrash is
disabled. This feature is meant to remind the user that libtrash is
disabled and that, for that reason, any deletions will be permanent.
This feature is disabled by default, so that libtrash remains
"invisible" to the user.


Other options: name of trash can, name of TRASH_SYSTEM_ROOT under your trash
can, whether to allow the destruction of the configuration file used by
libtrash, and what to do in case of error. You can also set in your
environment a list of exceptions to the list of unremovable directories.


To configure libtrash so that it better suits your purposes you should
edit the file libtrash.conf before compiling. Even if you won't be
configuring libtrash at compile-time, it is recommended that you at
least read config.txt so that you know how libtrash handles its
configuration files.



CONFIGURING, COMPILING, INSTALLING AND ACTIVATING libtrash:
----------------------------------------------------------


To configure:


1 - Edit the file libtrash.conf. All options are (verbosely) explained there.


To compile:

2 - Run "make".



To install:

3- Edit the Makefile, possibly choosing alternative locations for the shared
library and the system-wide, uneditable configuration file (defaults:
/usr/local/lib and /etc/libtrash.conf, respectively).

4- Run, as root, "make install".

This installs libtrash in the directory specified at the top of the
Makefile, runs ldconfig and puts a system-wide configuration file in
/etc/libtrash.conf reflecting the compile-time defaults used. NEVER EDIT
THIS FILE. USE A PERSONAL CONFIGURATION FILE INSTEAD. 

[Note that you can also install libtrash on your home directory: just
edit the top of the file src/Makefile and run 'make install' from your
account.]

5- Now go and read config.txt.



To activate libtrash:

6 - So that calls to the different GNU libc functions are intercepted,
you must "preload" this library. This is can be done in two ways:
either edit /etc/ld.so.preload or set the LD_PRELOAD environmental
variable. Each approach has its pros and cons.

(i) /etc/ld.so.preload: 
    
    + libtrash will be always on, even when you 'su' into another
      account without setting the environment (see LIMITATIONS);
    - You must be root.
    - It *can* screw up your system's boot and shutdown procedures.
    - It *can* make your system unusable if you make a mistake while
      typing the path to libtrash. (In that case, boot from a rescue
      disk and remove /etc/ld.so.preload.)
      
Just open /etc/ld.so.preload (creating it if it didn't previously
exist) and type the absolute path to libtrash (if you didn't modify
the INSTLIBDIR variable in the Makefile, that would be
"/usr/local/lib/libtrash.so" -- without the quotes). It is very
important that you check for typos and make sure that libtrash is in
fact installed at that location, otherwise your system will become
unusable! 

The other problem with this method is that it might (depending on your
distribution and on the setting of UNREMOVABLE_DIRS) prevent your
system from correctly booting and shutting down, because libtrash is
active all the time and prevents the system's boot and shutdown
scripts from removing/updating certain files. I know of two work-arounds for
this problem:

    - Store the path to libtrash in some other file (eg,
     /etc/ld.so.preload.off), and then have the *last* boot script (check
     your distribution's documentation) rename that file /etc/ld.so.preload
     when the boot process is (almost) finished. From that point on, libtrash
     is always on. Then, the first script which is run at shutdown renames
     that file /etc/ld.so.preload.off, so that libtrash won't be running
     during the shutdown process and while the system boots the next time.
     Downside: if for some reason the system crashes without shutting down
     properly it might not boot correctly, because libtrash will still be active.
    
    - Find out which files your system needs to modify in the protected
      directories while booting/shutting down and list them in the
      EXCEPTIONS configuration variable. This is what I use on my system.
      Just make sure that while testing you have a boot disk ready in case
      something goes wrong and the system doesn't boot. If you are lucky
      the default list in EXCEPTIONS will also work for you.

(ii) LD_PRELOAD: 

     + Doesn't require root access.
     + If something goes wrong, all you need to do is type "unset
       LD_PRELOAD". No risk of making your system unusable or causing
       boot/shutdown problems.
     - libtrash will only work if this variable is set. If, eg, you 'su'
       into an account without setting the user environment (ie,
       without using "su -"), then libtrash won't be activated.
       
Just run the command

$ export LD_PRELOAD=/usr/local/lib/libtrash.so

each time you log in (don't forget to use the correct path!). The same
effect can be achieved in a painless way by appending that line to a
file which gets executed whenever you log in, such as ~/.profile or
~/.bash_login. If you wish to activate libtrash for every user on the
system using this method, append that line to /etc/profile instead.
(Note: Your distribution might use different files for this purpose.
If you use a shell other than Bash, you probably know what to do in
your situation.)


TESTING libtrash:
----------------


libtrash should now be set up and ready to spare you a lot of headaches. You
can test drive it by doing the following (assuming that you didn't change
TRASH_CAN to a string other than "Trash"):

1) Create a file called test_file
2) Open test_file with a text editor, type a few characters and save it.
3) Run the following commands:

$ rm test_file
$ ls Trash/

test_file should now be stored in Trash/. But don't be fooled by this
example! libtrash isn't restricted to "saving" files which you explicitly
deleted with "rm": it also works with your (graphical) file manager, mail
user agent, etc...

(NOTE: Simply "touching" a test file -- ie, "touch test_file" -- and then
removing it will no longer put it in the trash can, because libtrash now
ignores empty files, since their removal doesn't present a risk of data
loss.)

SUSPENDING/RESUMING/CIRCUMVENTING libtrash:
------------------------------------------


Should you need to temporarily disable libtrash, you can do so by running
the command

$ export TRASH_OFF=YES

When you are done, libtrash can be reactivated by typing:

$ export TRASH_OFF=NO

You might make these operations simpler by appending the following two lines
to the init file you used in step 5) above (if you are using Bash as your
shell):

alias trash_on="export TRASH_OFF=NO"
alias trash_off="export TRASH_OFF=YES"

After doing so, you can enable/disable libtrash by typing 

$ trash_on

or

$ trash_off

at the prompt.

If you often need to remove one or more files in a definitive way using
'rm', you might wish to define

alias hardrm="TRASH_OFF=YES rm"

After having done so,

hardrm file.txt

will achieve the same effect as 

TRASH_OFF=YES rm file.txt

NOTE: I strongly advise AGAINST defining such an alias, because you
will probably get into the habit of always using it: at the time you
delete a file, you are always sure that you won't need it again... :-)
The habit of using that alias effectively makes installing libtrash
useless. Unless you wish to effectively do away with the file due to
privacy/confidentiality concerns, think instead of how cheap a
gigabyte of HD space is! :-)

If you have set the option SHOULD_WARN (see libtrash.conf), running a
command while TRASH_OFF is set to "YES" will result in libtrash
printing to stderr (at least) one reminder that it is currently
disabled.



LIMITATIONS:
-----------

1- As mentioned in the second note near the top of this document,
destroying documents in a partition different from the one on which
your home directory resides will result in a byte-after-byte copy of
those files into your trash can. If I could think of a faster, more
efficient way of doing that I would have already implemented it.
Unfortunately, things like quota-support and access permissions make
this problem hard to solve. Unless someone suggests a good way to
overcome this, this isn't going to change any time soon... Sorry!

2- As mentioned in the section on how to activate libtrash, the
LD_PRELOAD method doesn't protect you from mistakes while using an
account in which (for any reason) LD_PRELOAD isn't set and pointing to
libtrash. If you 'su' into other accounts, you should (i) make sure
that, by default, they have LD_PRELOAD pointing to libtrash and (ii)
always use "su - [user name]", instead of "su [user name]". The only
alternative is to activate libtrash from /etc/ld.so.preload.


CONTACT:
-------

This library was written by me, Manuel Arriaga. Feel free to contact me at
manuelarriaga@gmail.com with questions, suggestions, bug reports or just a
short note saying how libtrash helped you or your organization deploy
GNU/Linux in a context where some "user friendliness" in handling file
deletions is required.


CREDITS:
-------

- Avery Pennarun, whose "freestyle-concept" tarball showed me how to
intercept system calls and write a suitable Makefile.

- Phil Howard and wwp for pointing out problems with the (abandoned) hardrm
script. wwp also offered general advice.

- Karl Pitrich for letting me know about a bug in the calls to mkdir() and
chmod() in the code of dir_ok() which rendered the trash can (and all
subdirs) unbrowsable if you didn't manually correct their permissions with
'chmod'.

- Daniel Sadilek for letting me know that some people _did_ need inter-device
support :), the helpful cleanTrash Perl script and help testing libtrash-0.6.

- Ross Skaliotis for helping me pin down the cause of the incompatibility
between libtrash and Samba.

- Christoph Dworzak for reporting poor handling of special files, and
providing a patch.

- Martin Corley for the alternative cleanTrash script.

- Frederic Connes for reporting a bug affecting the creation of replacement
files when open()/open64() are being intercepted and suggesting the use of
different names for 5 configuration variables. Frederic also provided two
patches against the Makefile and cleanTrash script.

- Dan Stutzbach for reporting a bug in the function readline(), sending a
patch and helping me fix it.

- Ryan Brown for reporting a memory leak.

- BBBart for reporting a bug in the handling of files with names starting
with multiple dots.

- Jacek Sliwerski (rzyjontko) for adding the IGNORE_RE feature to libtrash.

- Robert Storey for reporting an error in the documentation.

- Raik Lieske for reporting a bug in the handling of certain file paths.

- David Benbennick for reporting mishandling of function calls with a NULL pathname.

- Jorgen Schaefer for helping me figure out why glibc was crashing when
libtrash was active and getwc() was called.