/[coreutils]/coreutils/src/remove.c
ViewVC logotype

Contents of /coreutils/src/remove.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.126 - (show annotations) (download)
Mon May 16 20:28:53 2005 UTC (18 years, 11 months ago) by eggert
Branch: MAIN
Changes since 1.125: +12 -8 lines
File MIME type: text/plain
Fix Cygwin porting problem reported by Eric Blake.
(DT_IS_DIR): Remove.
(DT_IS_KNOWN, DT_MUST_BE): New macros.
(remove_entry): Use them.

1 /* remove.c -- core functions for removing files and directories
2 Copyright (C) 88, 90, 91, 1994-2005 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18 /* Extracted from rm.c and librarified, then rewritten by Jim Meyering. */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <setjmp.h>
24 #include <assert.h>
25
26 #include "save-cwd.h"
27 #include "system.h"
28 #include "cycle-check.h"
29 #include "dirname.h"
30 #include "error.h"
31 #include "euidaccess.h"
32 #include "file-type.h"
33 #include "hash.h"
34 #include "hash-pjw.h"
35 #include "obstack.h"
36 #include "quote.h"
37 #include "remove.h"
38 #include "root-dev-ino.h"
39 #include "unlinkdir.h"
40 #include "yesno.h"
41
42 /* Avoid shadowing warnings because these are functions declared
43 in dirname.h as well as locals used below. */
44 #define dir_name rm_dir_name
45 #define dir_len rm_dir_len
46
47 #define obstack_chunk_alloc malloc
48 #define obstack_chunk_free free
49
50 /* This is the maximum number of consecutive readdir/unlink calls that
51 can be made (with no intervening rewinddir or closedir/opendir)
52 before triggering a bug that makes readdir return NULL even though
53 some directory entries have not been processed. The bug afflicts
54 SunOS's readdir when applied to ufs file systems and Darwin 6.5's
55 (and OSX v.10.3.8's) HFS+. This maximum is conservative in that
56 demonstrating the problem seems to require a directory containing
57 at least 254 deletable entries (which doesn't count . and ..), so
58 we could conceivably increase the maximum value to 254. */
59 enum
60 {
61 CONSECUTIVE_READDIR_UNLINK_THRESHOLD = 200
62 };
63
64 enum Ternary
65 {
66 T_UNKNOWN = 2,
67 T_NO,
68 T_YES
69 };
70 typedef enum Ternary Ternary;
71
72 /* The prompt function may be called twice for a given directory.
73 The first time, we ask whether to descend into it, and the
74 second time, we ask whether to remove it. */
75 enum Prompt_action
76 {
77 PA_DESCEND_INTO_DIR = 2,
78 PA_REMOVE_DIR
79 };
80
81 /* On systems with an lstat function that accepts the empty string,
82 arrange to make lstat calls go through the wrapper function. */
83 #if HAVE_LSTAT_EMPTY_STRING_BUG
84 int rpl_lstat (const char *, struct stat *);
85 # define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
86 #endif
87
88 /* Initial capacity of per-directory hash table of entries that have
89 been processed but not been deleted. */
90 #define HT_UNREMOVABLE_INITIAL_CAPACITY 13
91
92 /* An entry in the active directory stack.
93 Each entry corresponds to an `active' directory. */
94 struct AD_ent
95 {
96 /* For a given active directory, this is the set of names of
97 entries in that directory that could/should not be removed.
98 For example, `.' and `..', as well as files/dirs for which
99 unlink/rmdir failed e.g., due to access restrictions. */
100 Hash_table *unremovable;
101
102 /* Record the status for a given active directory; we need to know
103 whether an entry was not removed, either because of an error or
104 because the user declined. */
105 enum RM_status status;
106
107 /* The directory's dev/ino. Used to ensure that `chdir some-subdir', then
108 `chdir ..' takes us back to the same directory from which we started).
109 (valid for all but the bottommost entry on the stack. */
110 struct dev_ino dev_ino;
111 };
112
113 extern char *program_name;
114
115 struct dirstack_state
116 {
117 /* The name of the directory (starting with and relative to a command
118 line argument) being processed. When a subdirectory is entered, a new
119 component is appended (pushed). Remove (pop) the top component
120 upon chdir'ing out of a directory. This is used to form the full
121 name of the current directory or a file therein, when necessary. */
122 struct obstack dir_stack;
123
124 /* Stack of lengths of directory names (including trailing slash)
125 appended to dir_stack. We have to have a separate stack of lengths
126 (rather than just popping back to previous slash) because the first
127 element pushed onto the dir stack may contain slashes. */
128 struct obstack len_stack;
129
130 /* Stack of active directory entries.
131 The first `active' directory is the initial working directory.
132 Additional active dirs are pushed onto the stack as we `chdir'
133 into each directory to be processed. When finished with the
134 hierarchy under a directory, pop the active dir stack. */
135 struct obstack Active_dir;
136
137 /* Used to detect cycles. */
138 struct cycle_check_state cycle_check_state;
139
140 /* Target of a longjmp in case rm has to stop processing the current
141 command-line argument. This happens 1) when rm detects a directory
142 cycle or 2) when it has processed one or more directories, but then
143 is unable to return to the initial working directory to process
144 additional `.'-relative command-line arguments. */
145 jmp_buf current_arg_jumpbuf;
146 };
147 typedef struct dirstack_state Dirstack_state;
148
149 struct cwd_state
150 {
151 /* The value of errno after a failed save_cwd or restore_cwd. */
152 int saved_errno;
153
154 /* Information (open file descriptor or absolute directory name)
155 required in order to restore the initial working directory. */
156 struct saved_cwd saved_cwd;
157 };
158
159 static Dirstack_state *
160 ds_init (void)
161 {
162 Dirstack_state *ds = xmalloc (sizeof *ds);
163 obstack_init (&ds->dir_stack);
164 obstack_init (&ds->len_stack);
165 obstack_init (&ds->Active_dir);
166 return ds;
167 }
168
169 static void
170 ds_free (Dirstack_state *ds)
171 {
172 obstack_free (&ds->dir_stack, NULL);
173 obstack_free (&ds->len_stack, NULL);
174 obstack_free (&ds->Active_dir, NULL);
175 free (ds);
176 }
177
178 static void
179 hash_freer (void *x)
180 {
181 free (x);
182 }
183
184 static bool
185 hash_compare_strings (void const *x, void const *y)
186 {
187 return STREQ (x, y) ? true : false;
188 }
189
190 static inline void
191 push_dir (Dirstack_state *ds, const char *dir_name)
192 {
193 size_t len = strlen (dir_name);
194
195 /* Append the string onto the stack. */
196 obstack_grow (&ds->dir_stack, dir_name, len);
197
198 /* Append a trailing slash. */
199 obstack_1grow (&ds->dir_stack, '/');
200
201 /* Add one for the slash. */
202 ++len;
203
204 /* Push the length (including slash) onto its stack. */
205 obstack_grow (&ds->len_stack, &len, sizeof (len));
206 }
207
208 /* Return the entry name of the directory on the top of the stack
209 in malloc'd storage. */
210 static inline char *
211 top_dir (Dirstack_state const *ds)
212 {
213 size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
214 size_t *length = obstack_base (&ds->len_stack);
215 size_t top_len = length[n_lengths - 1];
216 char const *p = obstack_next_free (&ds->dir_stack) - top_len;
217 char *q = xmalloc (top_len);
218 memcpy (q, p, top_len - 1);
219 q[top_len - 1] = 0;
220 return q;
221 }
222
223 static inline void
224 pop_dir (Dirstack_state *ds)
225 {
226 size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
227 size_t *length = obstack_base (&ds->len_stack);
228 size_t top_len;
229
230 assert (n_lengths > 0);
231 top_len = length[n_lengths - 1];
232 assert (top_len >= 2);
233
234 /* Pop off the specified length of pathname. */
235 assert (obstack_object_size (&ds->dir_stack) >= top_len);
236 obstack_blank (&ds->dir_stack, -top_len);
237
238 /* Pop the length stack, too. */
239 assert (obstack_object_size (&ds->len_stack) >= sizeof (size_t));
240 obstack_blank (&ds->len_stack, -(int) sizeof (size_t));
241 }
242
243 /* Copy the SRC_LEN bytes of data beginning at SRC into the DST_LEN-byte
244 buffer, DST, so that the last source byte is at the end of the destination
245 buffer. If SRC_LEN is longer than DST_LEN, then set *TRUNCATED.
246 Set *RESULT to point to the beginning of (the portion of) the source data
247 in DST. Return the number of bytes remaining in the destination buffer. */
248
249 static size_t
250 right_justify (char *dst, size_t dst_len, const char *src, size_t src_len,
251 char **result, bool *truncated)
252 {
253 const char *sp;
254 char *dp;
255
256 if (src_len <= dst_len)
257 {
258 sp = src;
259 dp = dst + (dst_len - src_len);
260 *truncated = false;
261 }
262 else
263 {
264 sp = src + (src_len - dst_len);
265 dp = dst;
266 src_len = dst_len;
267 *truncated = true;
268 }
269
270 *result = memcpy (dp, sp, src_len);
271 return dst_len - src_len;
272 }
273
274 /* Using the global directory name obstack, create the full path to FILENAME.
275 Return it in sometimes-realloc'd space that should not be freed by the
276 caller. Realloc as necessary. If realloc fails, use a static buffer
277 and put as long a suffix in that buffer as possible. */
278
279 #define full_filename(Filename) full_filename_ (ds, Filename)
280 static char *
281 full_filename_ (Dirstack_state const *ds, const char *filename)
282 {
283 static char *buf = NULL;
284 static size_t n_allocated = 0;
285
286 size_t dir_len = obstack_object_size (&ds->dir_stack);
287 char *dir_name = obstack_base (&ds->dir_stack);
288 size_t n_bytes_needed;
289 size_t filename_len;
290
291 filename_len = strlen (filename);
292 n_bytes_needed = dir_len + filename_len + 1;
293
294 if (n_allocated < n_bytes_needed)
295 {
296 /* This code requires that realloc accept NULL as the first arg.
297 This function must not use xrealloc. Otherwise, an out-of-memory
298 error involving a file name to be expanded here wouldn't ever
299 be issued. Use realloc and fall back on using a static buffer
300 if memory allocation fails. */
301 char *new_buf = realloc (buf, n_bytes_needed);
302 n_allocated = n_bytes_needed;
303
304 if (new_buf == NULL)
305 {
306 #define SBUF_SIZE 512
307 #define ELLIPSES_PREFIX "[...]"
308 static char static_buf[SBUF_SIZE];
309 bool truncated;
310 size_t len;
311 char *p;
312
313 free (buf);
314 len = right_justify (static_buf, SBUF_SIZE, filename,
315 filename_len + 1, &p, &truncated);
316 right_justify (static_buf, len, dir_name, dir_len, &p, &truncated);
317 if (truncated)
318 {
319 memcpy (static_buf, ELLIPSES_PREFIX,
320 sizeof (ELLIPSES_PREFIX) - 1);
321 }
322 return p;
323 }
324
325 buf = new_buf;
326 }
327
328 if (filename_len == 1 && *filename == '.' && dir_len)
329 {
330 /* FILENAME is just `.' and dir_len is nonzero.
331 Copy the directory part, omitting the trailing slash,
332 and append a trailing zero byte. */
333 char *p = mempcpy (buf, dir_name, dir_len - 1);
334 *p = 0;
335 }
336 else
337 {
338 /* Copy the directory part, including trailing slash, and then
339 append the filename part, including a trailing zero byte. */
340 memcpy (mempcpy (buf, dir_name, dir_len), filename, filename_len + 1);
341 assert (strlen (buf) + 1 == n_bytes_needed);
342 }
343
344 return buf;
345 }
346
347 static size_t
348 AD_stack_height (Dirstack_state const *ds)
349 {
350 return obstack_object_size (&ds->Active_dir) / sizeof (struct AD_ent);
351 }
352
353 static struct AD_ent *
354 AD_stack_top (Dirstack_state const *ds)
355 {
356 return (struct AD_ent *)
357 ((char *) obstack_next_free (&ds->Active_dir) - sizeof (struct AD_ent));
358 }
359
360 static void
361 AD_stack_pop (Dirstack_state *ds)
362 {
363 /* operate on Active_dir. pop and free top entry */
364 struct AD_ent *top = AD_stack_top (ds);
365 if (top->unremovable)
366 hash_free (top->unremovable);
367 obstack_blank (&ds->Active_dir, -(int) sizeof (struct AD_ent));
368 pop_dir (ds);
369 }
370
371 /* chdir `up' one level.
372 Whenever using chdir '..', verify that the post-chdir
373 dev/ino numbers for `.' match the saved ones.
374 If they don't match, exit nonzero.
375 Set *PREV_DIR to the name (in malloc'd storage) of the
376 directory (usually now empty) from which we're coming.
377 If we're at the bottom of the AD stack (about to return
378 to the initial working directory), then use CWD.
379 If that restore_cwd fails, set CWD_STATE->saved_errno. */
380 static void
381 AD_pop_and_chdir (Dirstack_state *ds, char **prev_dir,
382 struct cwd_state *cwd_state)
383 {
384 enum RM_status old_status = AD_stack_top(ds)->status;
385 struct AD_ent *top;
386
387 /* Get the name of the current (but soon to be `previous') directory
388 from the top of the stack. */
389 *prev_dir = top_dir (ds);
390
391 AD_stack_pop (ds);
392 top = AD_stack_top (ds);
393
394 /* Propagate any failure to parent. */
395 UPDATE_STATUS (top->status, old_status);
396
397 assert (AD_stack_height (ds));
398
399 if (1 < AD_stack_height (ds))
400 {
401 struct stat sb;
402
403 /* We can give a better diagnostic here, since the target is relative. */
404 if (chdir ("..") != 0)
405 {
406 error (EXIT_FAILURE, errno,
407 _("cannot chdir from %s to .."),
408 quote (full_filename (".")));
409 }
410
411 if (lstat (".", &sb))
412 error (EXIT_FAILURE, errno,
413 _("cannot lstat `.' in %s"), quote (full_filename (".")));
414
415 /* Ensure that post-chdir dev/ino match the stored ones. */
416 if ( ! SAME_INODE (sb, top->dev_ino))
417 error (EXIT_FAILURE, 0,
418 _("%s changed dev/ino"), quote (full_filename (".")));
419 }
420 else
421 {
422 if (restore_cwd (&cwd_state->saved_cwd) != 0)
423 {
424 /* We've failed to return to the initial working directory.
425 That failure may be harmless if x->require_restore_cwd is false,
426 but we do have to remember that fact, including the errno value,
427 so we can give an accurate diagnostic when reporting the failure
428 to remove a subsequent relative-named command-line argument. */
429 cwd_state->saved_errno = errno;
430 }
431 }
432 }
433
434 /* Initialize *HT if it is NULL.
435 Insert FILENAME into HT. */
436 static void
437 AD_mark_helper (Hash_table **ht, char const *filename)
438 {
439 if (*ht == NULL)
440 {
441 *ht = hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY, NULL, hash_pjw,
442 hash_compare_strings, hash_freer);
443 if (*ht == NULL)
444 xalloc_die ();
445 }
446 if (! hash_insert (*ht, filename))
447 xalloc_die ();
448 }
449
450 /* Mark FILENAME (in current directory) as unremovable. */
451 static void
452 AD_mark_as_unremovable (Dirstack_state *ds, char const *filename)
453 {
454 AD_mark_helper (&AD_stack_top(ds)->unremovable, xstrdup (filename));
455 }
456
457 /* Mark the current directory as unremovable. I.e., mark the entry
458 in the parent directory corresponding to `.'.
459 This happens e.g., when an opendir fails and the only name
460 the caller has conveniently at hand is `.'. */
461 static void
462 AD_mark_current_as_unremovable (Dirstack_state *ds)
463 {
464 struct AD_ent *top = AD_stack_top (ds);
465 const char *curr = top_dir (ds);
466
467 assert (1 < AD_stack_height (ds));
468
469 --top;
470 AD_mark_helper (&top->unremovable, curr);
471 }
472
473 /* Push an initial dummy entry onto the stack.
474 This will always be the bottommost entry on the stack. */
475 static void
476 AD_push_initial (Dirstack_state *ds)
477 {
478 struct AD_ent *top;
479
480 /* Extend the stack. */
481 obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
482
483 /* Fill in the new values. */
484 top = AD_stack_top (ds);
485 top->unremovable = NULL;
486
487 /* These should never be used.
488 Give them values that might look suspicious
489 in a debugger or in a diagnostic. */
490 top->dev_ino.st_dev = TYPE_MAXIMUM (dev_t);
491 top->dev_ino.st_ino = TYPE_MAXIMUM (ino_t);
492 }
493
494 /* Push info about the current working directory (".") onto the
495 active directory stack. DIR is the ./-relative name through
496 which we've just `chdir'd to this directory. DIR_SB_FROM_PARENT
497 is the result of calling lstat on DIR from the parent of DIR. */
498 static void
499 AD_push (Dirstack_state *ds, char const *dir,
500 struct stat const *dir_sb_from_parent)
501 {
502 struct stat sb;
503 struct AD_ent *top;
504
505 push_dir (ds, dir);
506
507 if (lstat (".", &sb))
508 error (EXIT_FAILURE, errno,
509 _("cannot lstat `.' in %s"), quote (full_filename (".")));
510
511 if ( ! SAME_INODE (sb, *dir_sb_from_parent))
512 error (EXIT_FAILURE, 0,
513 _("%s changed dev/ino"), quote (full_filename (".")));
514
515 /* Extend the stack. */
516 obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
517
518 /* Fill in the new values. */
519 top = AD_stack_top (ds);
520 top->dev_ino.st_dev = sb.st_dev;
521 top->dev_ino.st_ino = sb.st_ino;
522 top->unremovable = NULL;
523 }
524
525 static bool
526 AD_is_removable (Dirstack_state const *ds, char const *file)
527 {
528 struct AD_ent *top = AD_stack_top (ds);
529 return ! (top->unremovable && hash_lookup (top->unremovable, file));
530 }
531
532 /* Return true if DIR is determined to be an empty directory
533 or if opendir or readdir fails. */
534 static bool
535 is_empty_dir (char const *dir)
536 {
537 DIR *dirp = opendir (dir);
538 struct dirent const *dp;
539 int saved_errno;
540
541 if (dirp == NULL)
542 return false;
543
544 errno = 0;
545 dp = readdir_ignoring_dot_and_dotdot (dirp);
546 saved_errno = errno;
547 closedir (dirp);
548 if (dp != NULL)
549 return false;
550 return saved_errno == 0 ? true : false;
551 }
552
553 /* Return true if FILE is not a symbolic link and it is not writable.
554 Also return true if FILE cannot be lstat'ed. Otherwise, return false.
555 If lstat succeeds, set *BUF_P to BUF.
556 This is to avoid calling euidaccess when FILE is a symlink. */
557 static bool
558 write_protected_non_symlink (char const *file,
559 struct stat **buf_p,
560 struct stat *buf)
561 {
562 if (lstat (file, buf) != 0)
563 return false;
564 *buf_p = buf;
565 if (S_ISLNK (buf->st_mode))
566 return false;
567 return euidaccess (file, W_OK) == -1 && errno == EACCES;
568 }
569
570 /* Prompt whether to remove FILENAME, if required via a combination of
571 the options specified by X and/or file attributes. If the file may
572 be removed, return RM_OK. If the user declines to remove the file,
573 return RM_USER_DECLINED. If not ignoring missing files and we
574 cannot lstat FILENAME, then return RM_ERROR.
575
576 Depending on MODE, ask whether to `descend into' or to `remove' the
577 directory FILENAME. MODE is ignored when FILENAME is not a directory.
578 Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
579 appropriate to try to remove it with rmdir (e.g. recursive mode).
580 Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.
581 Set *IS_DIR to T_YES or T_NO if we happen to determine whether
582 FILENAME is a directory. */
583 static enum RM_status
584 prompt (Dirstack_state const *ds, char const *filename,
585 struct rm_options const *x, enum Prompt_action mode,
586 Ternary *is_dir, Ternary *is_empty)
587 {
588 bool write_protected = false;
589 struct stat *sbuf = NULL;
590 struct stat buf;
591
592 *is_empty = T_UNKNOWN;
593 *is_dir = T_UNKNOWN;
594
595 if (((!x->ignore_missing_files & (x->interactive | x->stdin_tty))
596 && (write_protected = write_protected_non_symlink (filename,
597 &sbuf, &buf)))
598 || x->interactive)
599 {
600 if (sbuf == NULL)
601 {
602 sbuf = &buf;
603 if (lstat (filename, sbuf))
604 {
605 /* lstat failed. This happens e.g., with `rm '''. */
606 error (0, errno, _("cannot lstat %s"),
607 quote (full_filename (filename)));
608 return RM_ERROR;
609 }
610 }
611
612 if (S_ISDIR (sbuf->st_mode) && !x->recursive)
613 {
614 error (0, EISDIR, _("cannot remove directory %s"),
615 quote (full_filename (filename)));
616 return RM_ERROR;
617 }
618
619 /* Using permissions doesn't make sense for symlinks. */
620 if (S_ISLNK (sbuf->st_mode))
621 {
622 if ( ! x->interactive)
623 return RM_OK;
624 write_protected = false;
625 }
626
627 /* Issue the prompt. */
628 {
629 char const *quoted_name = quote (full_filename (filename));
630
631 *is_dir = (S_ISDIR (sbuf->st_mode) ? T_YES : T_NO);
632
633 /* FIXME: use a variant of error (instead of fprintf) that doesn't
634 append a newline. Then we won't have to declare program_name in
635 this file. */
636 if (S_ISDIR (sbuf->st_mode)
637 && x->recursive
638 && mode == PA_DESCEND_INTO_DIR
639 && ((*is_empty = (is_empty_dir (filename) ? T_YES : T_NO))
640 == T_NO))
641 fprintf (stderr,
642 (write_protected
643 ? _("%s: descend into write-protected directory %s? ")
644 : _("%s: descend into directory %s? ")),
645 program_name, quoted_name);
646 else
647 {
648 /* TRANSLATORS: You may find it more convenient to translate
649 the equivalent of _("%s: remove %s (write-protected) %s? ").
650 It should avoid grammatical problems with the output
651 of file_type. */
652 fprintf (stderr,
653 (write_protected
654 ? _("%s: remove write-protected %s %s? ")
655 : _("%s: remove %s %s? ")),
656 program_name, file_type (sbuf), quoted_name);
657 }
658
659 if (!yesno ())
660 return RM_USER_DECLINED;
661 }
662 }
663 return RM_OK;
664 }
665
666 #if HAVE_STRUCT_DIRENT_D_TYPE
667
668 /* True if the type of the directory entry D is known. */
669 # define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
670
671 /* True if the type of the directory entry D must be T. */
672 # define DT_MUST_BE(d, t) ((d)->d_type == (t))
673
674 #else
675 # define DT_IS_KNOWN(d) false
676 # define DT_MUST_BE(d, t) false
677 #endif
678
679 #define DO_UNLINK(Filename, X) \
680 do \
681 { \
682 if (unlink (Filename) == 0) \
683 { \
684 if ((X)->verbose) \
685 printf (_("removed %s\n"), quote (full_filename (Filename))); \
686 return RM_OK; \
687 } \
688 \
689 if (errno == ENOENT && (X)->ignore_missing_files) \
690 return RM_OK; \
691 } \
692 while (0)
693
694 #define DO_RMDIR(Filename, X) \
695 do \
696 { \
697 if (rmdir (Filename) == 0) \
698 { \
699 if ((X)->verbose) \
700 printf (_("removed directory: %s\n"), \
701 quote (full_filename (Filename))); \
702 return RM_OK; \
703 } \
704 \
705 if (errno == ENOENT && (X)->ignore_missing_files) \
706 return RM_OK; \
707 \
708 if (errno == ENOTEMPTY || errno == EEXIST) \
709 return RM_NONEMPTY_DIR; \
710 } \
711 while (0)
712
713 /* Remove the file or directory specified by FILENAME.
714 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
715 But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
716
717 static enum RM_status
718 remove_entry (Dirstack_state const *ds, char const *filename,
719 struct rm_options const *x, struct dirent const *dp)
720 {
721 Ternary is_dir;
722 Ternary is_empty_directory;
723 enum RM_status s = prompt (ds, filename, x, PA_DESCEND_INTO_DIR,
724 &is_dir, &is_empty_directory);
725
726 if (s != RM_OK)
727 return s;
728
729 /* Why bother with the following if/else block? Because on systems with
730 an unlink function that *can* unlink directories, we must determine the
731 type of each entry before removing it. Otherwise, we'd risk unlinking
732 an entire directory tree simply by unlinking a single directory; then
733 all the storage associated with that hierarchy would not be freed until
734 the next fsck. Not nice. To avoid that, on such slightly losing
735 systems, we need to call lstat to determine the type of each entry,
736 and that represents extra overhead that -- it turns out -- we can
737 avoid on non-losing systems, since there, unlink will never remove
738 a directory. Also, on systems where unlink may unlink directories,
739 we're forced to allow a race condition: we lstat a non-directory, then
740 go to unlink it, but in the mean time, a malicious someone has replaced
741 it with a directory. */
742
743 if (cannot_unlink_dir ())
744 {
745 if (is_dir == T_YES && ! x->recursive)
746 {
747 error (0, EISDIR, _("cannot remove directory %s"),
748 quote (full_filename (filename)));
749 return RM_ERROR;
750 }
751
752 /* is_empty_directory is set iff it's ok to use rmdir.
753 Note that it's set only in interactive mode -- in which case it's
754 an optimization that arranges so that the user is asked just
755 once whether to remove the directory. */
756 if (is_empty_directory == T_YES)
757 DO_RMDIR (filename, x);
758
759 /* If we happen to know that FILENAME is a directory, return now
760 and let the caller remove it -- this saves the overhead of a failed
761 unlink call. If FILENAME is a command-line argument, then dp is NULL,
762 so we'll first try to unlink it. Using unlink here is ok, because it
763 cannot remove a directory. */
764 if ((dp && DT_MUST_BE (dp, DT_DIR)) || is_dir == T_YES)
765 return RM_NONEMPTY_DIR;
766
767 DO_UNLINK (filename, x);
768
769 if (! x->recursive
770 || errno == ENOENT || errno == ENOTDIR
771 || errno == ELOOP || errno == ENAMETOOLONG)
772 {
773 /* Either --recursive is not in effect, or the file cannot be a
774 directory. Report the unlink problem and fail. */
775 error (0, errno, _("cannot remove %s"),
776 quote (full_filename (filename)));
777 return RM_ERROR;
778 }
779 }
780 else
781 {
782 /* If we don't already know whether FILENAME is a directory, find out now.
783 Then, if it's a non-directory, we can use unlink on it. */
784 if (is_dir == T_UNKNOWN)
785 {
786 if (dp && DT_IS_KNOWN (dp))
787 is_dir = DT_MUST_BE (dp, DT_DIR) ? T_YES : T_NO;
788 else
789 {
790 struct stat sbuf;
791 if (lstat (filename, &sbuf))
792 {
793 if (errno == ENOENT && x->ignore_missing_files)
794 return RM_OK;
795
796 error (0, errno, _("cannot lstat %s"),
797 quote (full_filename (filename)));
798 return RM_ERROR;
799 }
800
801 is_dir = S_ISDIR (sbuf.st_mode) ? T_YES : T_NO;
802 }
803 }
804
805 if (is_dir == T_NO)
806 {
807 /* At this point, barring race conditions, FILENAME is known
808 to be a non-directory, so it's ok to try to unlink it. */
809 DO_UNLINK (filename, x);
810
811 /* unlink failed with some other error code. report it. */
812 error (0, errno, _("cannot remove %s"),
813 quote (full_filename (filename)));
814 return RM_ERROR;
815 }
816
817 if (! x->recursive)
818 {
819 error (0, EISDIR, _("cannot remove directory %s"),
820 quote (full_filename (filename)));
821 return RM_ERROR;
822 }
823
824 if (is_empty_directory == T_YES)
825 {
826 DO_RMDIR (filename, x);
827 /* Don't diagnose any failure here.
828 It'll be detected when the caller tries another way. */
829 }
830 }
831
832 return RM_NONEMPTY_DIR;
833 }
834
835 /* Remove entries in `.', the current working directory (cwd).
836 Upon finding a directory that is both non-empty and that can be chdir'd
837 into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
838 SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
839 NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
840 Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
841 Return RM_OK if all entries are removed. Return RM_ERROR if any
842 entry cannot be removed. Otherwise, return RM_USER_DECLINED if
843 the user declines to remove at least one entry. Remove as much as
844 possible, continuing even if we fail to remove some entries. */
845 static enum RM_status
846 remove_cwd_entries (Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
847 struct rm_options const *x)
848 {
849 DIR *dirp = opendir (".");
850 struct AD_ent *top = AD_stack_top (ds);
851 enum RM_status status = top->status;
852 size_t n_unlinked_since_opendir_or_last_rewind = 0;
853
854 assert (VALID_STATUS (status));
855 *subdir = NULL;
856
857 if (dirp == NULL)
858 {
859 if (errno != ENOENT || !x->ignore_missing_files)
860 {
861 error (0, errno, _("cannot open directory %s"),
862 quote (full_filename (".")));
863 return RM_ERROR;
864 }
865 }
866
867 while (1)
868 {
869 struct dirent const *dp;
870 enum RM_status tmp_status;
871 const char *f;
872
873 /* Set errno to zero so we can distinguish between a readdir failure
874 and when readdir simply finds that there are no more entries. */
875 errno = 0;
876 if ((dp = readdir_ignoring_dot_and_dotdot (dirp)) == NULL)
877 {
878 if (errno)
879 {
880 /* Save/restore errno across closedir call. */
881 int e = errno;
882 closedir (dirp);
883 errno = e;
884
885 /* Arrange to give a diagnostic after exiting this loop. */
886 dirp = NULL;
887 }
888 else if (CONSECUTIVE_READDIR_UNLINK_THRESHOLD
889 < n_unlinked_since_opendir_or_last_rewind)
890 {
891 /* Call rewinddir if we've called unlink or rmdir so many times
892 (since the opendir or the previous rewinddir) that this
893 NULL-return may be the symptom of a buggy readdir. */
894 rewinddir (dirp);
895 n_unlinked_since_opendir_or_last_rewind = 0;
896 continue;
897 }
898 break;
899 }
900
901 f = dp->d_name;
902
903 /* Skip files we've already tried/failed to remove. */
904 if ( ! AD_is_removable (ds, f))
905 continue;
906
907 /* Pass dp->d_type info to remove_entry so the non-glibc
908 case can decide whether to use unlink or chdir.
909 Systems without the d_type member will have to endure
910 the performance hit of first calling lstat F. */
911 tmp_status = remove_entry (ds, f, x, dp);
912 switch (tmp_status)
913 {
914 case RM_OK:
915 /* Count how many files we've unlinked since the initial
916 opendir or the last rewinddir. On buggy systems, if you
917 remove too many, readdir returns NULL even though there
918 remain unprocessed directory entries. */
919 ++n_unlinked_since_opendir_or_last_rewind;
920 break;
921
922 case RM_ERROR:
923 case RM_USER_DECLINED:
924 AD_mark_as_unremovable (ds, f);
925 UPDATE_STATUS (status, tmp_status);
926 break;
927
928 case RM_NONEMPTY_DIR:
929 {
930 /* Save a copy of errno, in case the preceding unlink (from
931 remove_entry's DO_UNLINK) of a non-directory failed. */
932 int saved_errno = errno;
933
934 /* Record dev/ino of F so that we can compare
935 that with dev/ino of `.' after the chdir.
936 This dev/ino pair is also used in cycle detection. */
937 if (lstat (f, subdir_sb))
938 error (EXIT_FAILURE, errno, _("cannot lstat %s"),
939 quote (full_filename (f)));
940
941 errno = ENOTDIR;
942 if (! S_ISDIR (subdir_sb->st_mode) || chdir (f) != 0)
943 {
944 /* It is much more common that we reach this point for an
945 inaccessible directory. Hence the second diagnostic, below.
946 However it is also possible that F is a non-directory.
947 That can happen when we use the `! UNLINK_CAN_UNLINK_DIRS'
948 block of code and when DO_UNLINK fails due to EPERM.
949 In that case, give a better diagnostic. */
950 if (errno == ENOTDIR)
951 error (0, saved_errno, _("cannot remove %s"),
952 quote (full_filename (f)));
953 else
954 error (0, errno, _("cannot chdir from %s to %s"),
955 quote_n (0, full_filename (".")), quote_n (1, f));
956 AD_mark_as_unremovable (ds, f);
957 status = RM_ERROR;
958 break;
959 }
960 if (cycle_check (&ds->cycle_check_state, subdir_sb))
961 {
962 error (0, 0, _("\
963 WARNING: Circular directory structure.\n\
964 This almost certainly means that you have a corrupted file system.\n\
965 NOTIFY YOUR SYSTEM MANAGER.\n\
966 The following directory is part of the cycle:\n %s\n"),
967 quote (full_filename (".")));
968 longjmp (ds->current_arg_jumpbuf, 1);
969 }
970
971 *subdir = xstrdup (f);
972 break;
973 }
974 }
975
976 /* Record status for this directory. */
977 UPDATE_STATUS (top->status, status);
978
979 if (*subdir)
980 break;
981 }
982
983 if (dirp == NULL || CLOSEDIR (dirp) != 0)
984 {
985 /* Note that this diagnostic serves for both readdir
986 and closedir failures. */
987 error (0, errno, _("reading directory %s"), quote (full_filename (".")));
988 status = RM_ERROR;
989 }
990
991 return status;
992 }
993
994 /* Do this after each call to AD_push or AD_push_initial.
995 Because the status = RM_OK bit is too remove-specific to
996 go into the general-purpose AD_* package. */
997 #define AD_INIT_OTHER_MEMBERS() \
998 do \
999 { \
1000 AD_stack_top(ds)->status = RM_OK; \
1001 } \
1002 while (0)
1003
1004 /* Remove the hierarchy rooted at DIR.
1005 Do that by changing into DIR, then removing its contents, then
1006 returning to the original working directory and removing DIR itself.
1007 Don't use recursion. Be careful when using chdir ".." that we
1008 return to the same directory from which we came, if necessary.
1009 Return 1 for success, 0 if some file cannot be removed or if
1010 a chdir fails.
1011 If the initial working directory cannot be saved or restored,
1012 record the offending errno value in (*CWD_STATE)->saved_errno. */
1013
1014 static enum RM_status
1015 remove_dir (Dirstack_state *ds, char const *dir, struct cwd_state **cwd_state,
1016 struct rm_options const *x)
1017 {
1018 enum RM_status status;
1019 struct stat dir_sb;
1020
1021 /* Save any errno (from caller's failed remove_entry call), in case DIR
1022 is not a directory, so that we can give a reasonable diagnostic. */
1023 int saved_errno = errno;
1024
1025 if (*cwd_state == NULL)
1026 {
1027 *cwd_state = xmalloc (sizeof **cwd_state);
1028
1029 if (save_cwd (&(*cwd_state)->saved_cwd) != 0)
1030 {
1031 (*cwd_state)->saved_errno = errno;
1032 assert (errno != 0);
1033
1034 /* Pretend we started from "/". That is fine as long as there
1035 is no requirement to return to the original working directory.
1036 Use "/", not ".", so that we chdir out of a non-root target
1037 directory before attempting to remove it: some hosts don't let
1038 you remove a working directory. */
1039 (*cwd_state)->saved_cwd.name = xstrdup ("/");
1040 }
1041 else
1042 (*cwd_state)->saved_errno = 0;
1043
1044 AD_push_initial (ds);
1045 AD_INIT_OTHER_MEMBERS ();
1046 }
1047
1048 /* If we've failed to record and/or restore the initial working directory,
1049 and we're now trying to access a `.'-relative file name, then give a
1050 diagnostic, record the failure, and proceed with any subsequent
1051 command-line arguments. */
1052 if ((*cwd_state)->saved_errno && IS_RELATIVE_FILE_NAME (dir))
1053 {
1054 error (0, (*cwd_state)->saved_errno, _("cannot remove directory %s"),
1055 quote (full_filename (dir)));
1056 longjmp (ds->current_arg_jumpbuf, 1);
1057 }
1058
1059 /* There is a race condition in that an attacker could replace the nonempty
1060 directory, DIR, with a symlink between the preceding call to rmdir
1061 (in our caller) and the chdir below. However, the following lstat,
1062 along with the `stat (".",...' and dev/ino comparison in AD_push
1063 ensure that we detect it and fail. */
1064
1065 if (lstat (dir, &dir_sb))
1066 {
1067 error (0, errno,
1068 _("cannot lstat %s"), quote (full_filename (dir)));
1069 return RM_ERROR;
1070 }
1071
1072 errno = ENOTDIR;
1073 if (! S_ISDIR (dir_sb.st_mode) || chdir (dir) != 0)
1074 {
1075 if (errno == ENOTDIR)
1076 {
1077 error (0, saved_errno,
1078 _("cannot remove %s"), quote (full_filename (dir)));
1079 }
1080 else
1081 {
1082 error (0, errno,
1083 _("cannot chdir from %s to %s"),
1084 quote_n (0, full_filename (".")), quote_n (1, dir));
1085 }
1086 return RM_ERROR;
1087 }
1088
1089 if (ROOT_DEV_INO_CHECK (x->root_dev_ino, &dir_sb))
1090 {
1091 ROOT_DEV_INO_WARN (full_filename (dir));
1092 return 1;
1093 }
1094
1095 AD_push (ds, dir, &dir_sb);
1096 AD_INIT_OTHER_MEMBERS ();
1097
1098 status = RM_OK;
1099
1100 while (1)
1101 {
1102 char *subdir = NULL;
1103 struct stat subdir_sb;
1104 enum RM_status tmp_status = remove_cwd_entries (ds,
1105 &subdir, &subdir_sb, x);
1106 if (tmp_status != RM_OK)
1107 {
1108 UPDATE_STATUS (status, tmp_status);
1109 AD_mark_current_as_unremovable (ds);
1110 }
1111 if (subdir)
1112 {
1113 AD_push (ds, subdir, &subdir_sb);
1114 AD_INIT_OTHER_MEMBERS ();
1115
1116 free (subdir);
1117 continue;
1118 }
1119
1120 /* Execution reaches this point when we've removed the last
1121 removable entry from the current directory. */
1122 {
1123 /* This is the name of the directory that we have just
1124 returned from, after nominally removing all of its contents. */
1125 char *empty_dir;
1126
1127 AD_pop_and_chdir (ds, &empty_dir, *cwd_state);
1128
1129 /* Try to remove D only if remove_cwd_entries succeeded. */
1130 if (tmp_status == RM_OK)
1131 {
1132 /* This does a little more work than necessary when it actually
1133 prompts the user. E.g., we already know that D is a directory
1134 and that it's almost certainly empty, yet we lstat it.
1135 But that's no big deal since we're interactive. */
1136 Ternary is_dir;
1137 Ternary is_empty;
1138 enum RM_status s = prompt (ds, empty_dir, x, PA_REMOVE_DIR,
1139 &is_dir, &is_empty);
1140
1141 if (s != RM_OK)
1142 {
1143 free (empty_dir);
1144 return s;
1145 }
1146
1147 if (rmdir (empty_dir) == 0)
1148 {
1149 if (x->verbose)
1150 printf (_("removed directory: %s\n"),
1151 quote (full_filename (empty_dir)));
1152 }
1153 else
1154 {
1155 error (0, errno, _("cannot remove directory %s"),
1156 quote (full_filename (empty_dir)));
1157 AD_mark_as_unremovable (ds, empty_dir);
1158 status = RM_ERROR;
1159 UPDATE_STATUS (AD_stack_top(ds)->status, status);
1160 }
1161 }
1162
1163 free (empty_dir);
1164
1165 if (AD_stack_height (ds) == 1)
1166 break;
1167 }
1168 }
1169
1170 return status;
1171 }
1172
1173 /* Remove the file or directory specified by FILENAME.
1174 Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
1175 On input, the first time this function is called, CWD_STATE should be
1176 the address of a NULL pointer. Do not modify it for any subsequent calls.
1177 On output, it is either that same NULL pointer or the address of
1178 a malloc'd `struct saved_cwd' that may be freed. */
1179
1180 static enum RM_status
1181 rm_1 (Dirstack_state *ds, char const *filename,
1182 struct rm_options const *x, struct cwd_state **cwd_state)
1183 {
1184 char *base = base_name (filename);
1185 enum RM_status status;
1186
1187 if (DOT_OR_DOTDOT (base))
1188 {
1189 error (0, 0, _("cannot remove `.' or `..'"));
1190 return RM_ERROR;
1191 }
1192
1193 if (*cwd_state && (*cwd_state)->saved_errno
1194 && IS_RELATIVE_FILE_NAME (filename))
1195 {
1196 error (0, (*cwd_state)->saved_errno,
1197 _("cannot remove %s"), quote (filename));
1198 return RM_ERROR;
1199 }
1200
1201 status = remove_entry (ds, filename, x, NULL);
1202 if (status != RM_NONEMPTY_DIR)
1203 return status;
1204
1205 return remove_dir (ds, filename, cwd_state, x);
1206 }
1207
1208 /* Remove all files and/or directories specified by N_FILES and FILE.
1209 Apply the options in X. If X->require_restore_cwd is false, then
1210 this function may return RM_OK even though it is unable to restore
1211 the initial working directory. */
1212 extern enum RM_status
1213 rm (size_t n_files, char const *const *file, struct rm_options const *x)
1214 {
1215 struct cwd_state *cwd_state = NULL;
1216 Dirstack_state *ds;
1217
1218 /* Put the following two variables in static storage, so they can't
1219 be clobbered by the potential longjmp into this function. */
1220 static enum RM_status status = RM_OK;
1221 static size_t i;
1222
1223 ds = ds_init ();
1224
1225 for (i = 0; i < n_files; i++)
1226 {
1227 enum RM_status s;
1228 cycle_check_init (&ds->cycle_check_state);
1229 /* In the event that rm_1->remove_dir->remove_cwd_entries detects
1230 a directory cycle, arrange to fail, give up on this FILE, but
1231 continue on with any other arguments. */
1232 if (setjmp (ds->current_arg_jumpbuf))
1233 s = RM_ERROR;
1234 else
1235 s = rm_1 (ds, file[i], x, &cwd_state);
1236 assert (VALID_STATUS (s));
1237 UPDATE_STATUS (status, s);
1238 }
1239
1240 if (x->require_restore_cwd && cwd_state && cwd_state->saved_errno != 0)
1241 {
1242 error (0, cwd_state->saved_errno,
1243 _("cannot restore current working directory"));
1244 status = RM_ERROR;
1245 }
1246
1247 ds_free (ds);
1248
1249 if (cwd_state && cwd_state->saved_errno == 0)
1250 free_cwd (&cwd_state->saved_cwd);
1251
1252 free (cwd_state);
1253
1254 return status;
1255 }

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26