TODO: add an item for a chmod optimization
[platform/upstream/coreutils.git] / src / remove.c
1 /* remove.c -- core functions for removing files and directories
2    Copyright (C) 88, 90, 91, 1994-2008 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 3 of the License, or
7    (at your option) 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, see <http://www.gnu.org/licenses/>.  */
16
17 /* Extracted from rm.c and librarified, then rewritten by Jim Meyering.  */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <setjmp.h>
23 #include <assert.h>
24
25 #include "system.h"
26 #include "cycle-check.h"
27 #include "dirfd.h"
28 #include "error.h"
29 #include "euidaccess.h"
30 #include "euidaccess-stat.h"
31 #include "file-type.h"
32 #include "hash.h"
33 #include "hash-pjw.h"
34 #include "lstat.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 "write-any-file.h"
41 #include "yesno.h"
42
43 /* Avoid shadowing warnings because these are functions declared
44    in dirname.h as well as locals used below.  */
45 #define dir_name rm_dir_name
46 #define dir_len rm_dir_len
47
48 #define obstack_chunk_alloc malloc
49 #define obstack_chunk_free free
50
51 /* This is the maximum number of consecutive readdir/unlink calls that
52    can be made (with no intervening rewinddir or closedir/opendir) before
53    triggering a bug that makes readdir return NULL even though some
54    directory entries have not been processed.  The bug afflicts SunOS's
55    readdir when applied to ufs file systems and Darwin 6.5's (and OSX
56    v.10.3.8's) HFS+.  This maximum is conservative in that demonstrating
57    the problem requires a directory containing at least 16 deletable
58    entries (which doesn't count . and ..).
59    This problem also affects Darwin 7.9.0 (aka MacOS X 10.3.9) on HFS+
60    and NFS-mounted file systems, but not vfat ones.  */
61 enum
62   {
63     CONSECUTIVE_READDIR_UNLINK_THRESHOLD = 10
64   };
65
66 /* FIXME: in 2009, or whenever Darwin 7.9.0 (aka MacOS X 10.3.9) is no
67    longer relevant, remove this work-around code.  Then, there will be
68    no need to perform the extra rewinddir call, ever.  */
69 #define NEED_REWIND(readdir_unlink_count) \
70   (CONSECUTIVE_READDIR_UNLINK_THRESHOLD <= (readdir_unlink_count))
71
72 enum Ternary
73   {
74     T_UNKNOWN = 2,
75     T_NO,
76     T_YES
77   };
78 typedef enum Ternary Ternary;
79
80 /* The prompt function may be called twice for a given directory.
81    The first time, we ask whether to descend into it, and the
82    second time, we ask whether to remove it.  */
83 enum Prompt_action
84   {
85     PA_DESCEND_INTO_DIR = 2,
86     PA_REMOVE_DIR
87   };
88
89 /* Initial capacity of per-directory hash table of entries that have
90    been processed but not been deleted.  */
91 enum { HT_UNREMOVABLE_INITIAL_CAPACITY = 13 };
92
93 /* An entry in the active directory stack.
94    Each entry corresponds to an `active' directory.  */
95 struct AD_ent
96 {
97   /* For a given active directory, this is the set of names of
98      entries in that directory that could/should not be removed.
99      For example, `.' and `..', as well as files/dirs for which
100      unlink/rmdir failed e.g., due to access restrictions.  */
101   Hash_table *unremovable;
102
103   /* Record the status for a given active directory; we need to know
104      whether an entry was not removed, either because of an error or
105      because the user declined.  */
106   enum RM_status status;
107
108   /* The directory's dev/ino.  Used to ensure that a malicious user does
109      not replace a directory we're about to process with a symlink to
110      some other directory.  */
111   struct dev_ino dev_ino;
112 };
113
114 /* D_TYPE(D) is the type of directory entry D if known, DT_UNKNOWN
115    otherwise.  */
116 #if HAVE_STRUCT_DIRENT_D_TYPE
117 # define D_TYPE(d) ((d)->d_type)
118 #else
119 # define D_TYPE(d) DT_UNKNOWN
120
121 /* Any int values will do here, so long as they're distinct.
122    Undef any existing macros out of the way.  */
123 # undef DT_UNKNOWN
124 # undef DT_DIR
125 # undef DT_LNK
126 # define DT_UNKNOWN 0
127 # define DT_DIR 1
128 # define DT_LNK 2
129 #endif
130
131 struct dirstack_state
132 {
133   /* The name of the directory (starting with and relative to a command
134      line argument) being processed.  When a subdirectory is entered, a new
135      component is appended (pushed).  Remove (pop) the top component
136      upon chdir'ing out of a directory.  This is used to form the full
137      name of the current directory or a file therein, when necessary.  */
138   struct obstack dir_stack;
139
140   /* Stack of lengths of directory names (including trailing slash)
141      appended to dir_stack.  We have to have a separate stack of lengths
142      (rather than just popping back to previous slash) because the first
143      element pushed onto the dir stack may contain slashes.  */
144   struct obstack len_stack;
145
146   /* Stack of active directory entries.
147      The first `active' directory is the initial working directory.
148      Additional active dirs are pushed onto the stack as we `chdir'
149      into each directory to be processed.  When finished with the
150      hierarchy under a directory, pop the active dir stack.  */
151   struct obstack Active_dir;
152
153   /* Used to detect cycles.  */
154   struct cycle_check_state cycle_check_state;
155
156   /* Target of a longjmp in case rm has to stop processing the current
157      command-line argument.  This happens 1) when rm detects a directory
158      cycle or 2) when it has processed one or more directories, but then
159      is unable to return to the initial working directory to process
160      additional `.'-relative command-line arguments.  */
161   jmp_buf current_arg_jumpbuf;
162 };
163 typedef struct dirstack_state Dirstack_state;
164
165 /* A static buffer and its allocated size, these variables are used by
166    xfull_filename and full_filename to form full, relative file names.  */
167 static char *g_buf;
168 static size_t g_n_allocated;
169
170 /* Like fstatat, but cache the result.  If ST->st_size is -1, the
171    status has not been gotten yet.  If less than -1, fstatat failed
172    with errno == ST->st_ino.  Otherwise, the status has already
173    been gotten, so return 0.  */
174 static int
175 cache_fstatat (int fd, char const *file, struct stat *st, int flag)
176 {
177   if (st->st_size == -1 && fstatat (fd, file, st, flag) != 0)
178     {
179       st->st_size = -2;
180       st->st_ino = errno;
181     }
182   if (0 <= st->st_size)
183     return 0;
184   errno = (int) st->st_ino;
185   return -1;
186 }
187
188 /* Initialize a fstatat cache *ST.  Return ST for convenience.  */
189 static inline struct stat *
190 cache_stat_init (struct stat *st)
191 {
192   st->st_size = -1;
193   return st;
194 }
195
196 /* Return true if *ST has been statted.  */
197 static inline bool
198 cache_statted (struct stat *st)
199 {
200   return (st->st_size != -1);
201 }
202
203 /* Return true if *ST has been statted successfully.  */
204 static inline bool
205 cache_stat_ok (struct stat *st)
206 {
207   return (0 <= st->st_size);
208 }
209
210
211 static void
212 hash_freer (void *x)
213 {
214   free (x);
215 }
216
217 static bool
218 hash_compare_strings (void const *x, void const *y)
219 {
220   return STREQ (x, y) ? true : false;
221 }
222
223 static inline void
224 push_dir (Dirstack_state *ds, const char *dir_name)
225 {
226   size_t len = strlen (dir_name);
227
228   /* Don't copy trailing slashes.  */
229   while (1 < len && dir_name[len - 1] == '/')
230     --len;
231
232   /* Append the string onto the stack.  */
233   obstack_grow (&ds->dir_stack, dir_name, len);
234
235   /* Append a trailing slash.  */
236   obstack_1grow (&ds->dir_stack, '/');
237
238   /* Add one for the slash.  */
239   ++len;
240
241   /* Push the length (including slash) onto its stack.  */
242   obstack_grow (&ds->len_stack, &len, sizeof (len));
243 }
244
245 /* Return the entry name of the directory on the top of the stack
246    in malloc'd storage.  */
247 static inline char *
248 top_dir (Dirstack_state const *ds)
249 {
250   size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
251   size_t *length = obstack_base (&ds->len_stack);
252   size_t top_len = length[n_lengths - 1];
253   char const *p = obstack_next_free (&ds->dir_stack) - top_len;
254   char *q = xmalloc (top_len);
255   memcpy (q, p, top_len - 1);
256   q[top_len - 1] = 0;
257   return q;
258 }
259
260 static inline void
261 pop_dir (Dirstack_state *ds)
262 {
263   size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
264   size_t *length = obstack_base (&ds->len_stack);
265
266   assert (n_lengths > 0);
267   size_t top_len = length[n_lengths - 1];
268   assert (top_len >= 2);
269
270   /* Pop the specified length of file name.  */
271   assert (obstack_object_size (&ds->dir_stack) >= top_len);
272   obstack_blank (&ds->dir_stack, -top_len);
273
274   /* Pop the length stack, too.  */
275   assert (obstack_object_size (&ds->len_stack) >= sizeof (size_t));
276   obstack_blank (&ds->len_stack, -(int) sizeof (size_t));
277 }
278
279 /* Copy the SRC_LEN bytes of data beginning at SRC into the DST_LEN-byte
280    buffer, DST, so that the last source byte is at the end of the destination
281    buffer.  If SRC_LEN is longer than DST_LEN, then set *TRUNCATED.
282    Set *RESULT to point to the beginning of (the portion of) the source data
283    in DST.  Return the number of bytes remaining in the destination buffer.  */
284
285 static size_t
286 right_justify (char *dst, size_t dst_len, const char *src, size_t src_len,
287                char **result, bool *truncated)
288 {
289   const char *sp;
290   char *dp;
291
292   if (src_len <= dst_len)
293     {
294       sp = src;
295       dp = dst + (dst_len - src_len);
296       *truncated = false;
297     }
298   else
299     {
300       sp = src + (src_len - dst_len);
301       dp = dst;
302       src_len = dst_len;
303       *truncated = true;
304     }
305
306   *result = memcpy (dp, sp, src_len);
307   return dst_len - src_len;
308 }
309
310 /* Using the global directory name obstack, create the full name of FILENAME.
311    Return it in sometimes-realloc'd space that should not be freed by the
312    caller.  Realloc as necessary.  If realloc fails, return NULL.  */
313
314 static char *
315 full_filename0 (Dirstack_state const *ds, const char *filename)
316 {
317   size_t dir_len = obstack_object_size (&ds->dir_stack);
318   char *dir_name = obstack_base (&ds->dir_stack);
319   size_t filename_len = strlen (filename);
320   size_t n_bytes_needed = dir_len + filename_len + 1;
321
322   if (g_n_allocated < n_bytes_needed)
323     {
324       char *new_buf = realloc (g_buf, n_bytes_needed);
325       if (new_buf == NULL)
326         return NULL;
327
328       g_buf = new_buf;
329       g_n_allocated = n_bytes_needed;
330     }
331
332   if (STREQ (filename, ".") && dir_len)
333     {
334       /* FILENAME is just `.' and dir_len is nonzero.
335          Copy the directory part, omitting the trailing slash,
336          and append a trailing zero byte.  */
337       char *p = mempcpy (g_buf, dir_name, dir_len - 1);
338       *p = 0;
339     }
340   else
341     {
342       /* Copy the directory part, including trailing slash, and then
343          append the filename part, including a trailing zero byte.  */
344       memcpy (mempcpy (g_buf, dir_name, dir_len), filename, filename_len + 1);
345       assert (strlen (g_buf) + 1 == n_bytes_needed);
346     }
347
348   return g_buf;
349 }
350
351 /* Using the global directory name obstack, create the full name of FILENAME.
352    Return it in sometimes-realloc'd space that should not be freed by the
353    caller.  Realloc as necessary.  If realloc fails, die.  */
354
355 static char *
356 xfull_filename (Dirstack_state const *ds, const char *filename)
357 {
358   char *buf = full_filename0 (ds, filename);
359   if (buf == NULL)
360     xalloc_die ();
361   return buf;
362 }
363
364 /* Using the global directory name obstack, create the full name FILENAME.
365    Return it in sometimes-realloc'd space that should not be freed by the
366    caller.  Realloc as necessary.  If realloc fails, use a static buffer
367    and put as long a suffix in that buffer as possible.  Be careful not
368    to change errno.  */
369
370 #define full_filename(Filename) full_filename_ (ds, Filename)
371 static char *
372 full_filename_ (Dirstack_state const *ds, const char *filename)
373 {
374   int saved_errno = errno;
375   char *full_name = full_filename0 (ds, filename);
376   if (full_name)
377     {
378       errno = saved_errno;
379       return full_name;
380     }
381
382   {
383 #define SBUF_SIZE 512
384 #define ELLIPSES_PREFIX "[...]"
385     static char static_buf[SBUF_SIZE];
386     bool file_truncated;
387     bool dir_truncated;
388     size_t n_bytes_remaining;
389     char *p;
390     char *dir_name = obstack_base (&ds->dir_stack);
391     size_t dir_len = obstack_object_size (&ds->dir_stack);
392
393     free (g_buf);
394     n_bytes_remaining = right_justify (static_buf, SBUF_SIZE, filename,
395                                        strlen (filename) + 1, &p,
396                                        &file_truncated);
397     right_justify (static_buf, n_bytes_remaining, dir_name, dir_len,
398                    &p, &dir_truncated);
399     if (file_truncated || dir_truncated)
400       {
401         memcpy (static_buf, ELLIPSES_PREFIX,
402                 sizeof (ELLIPSES_PREFIX) - 1);
403       }
404     errno = saved_errno;
405     return p;
406   }
407 }
408
409 static inline size_t
410 AD_stack_height (Dirstack_state const *ds)
411 {
412   return obstack_object_size (&ds->Active_dir) / sizeof (struct AD_ent);
413 }
414
415 static inline struct AD_ent *
416 AD_stack_top (Dirstack_state const *ds)
417 {
418   return (struct AD_ent *)
419     ((char *) obstack_next_free (&ds->Active_dir) - sizeof (struct AD_ent));
420 }
421
422 static void
423 AD_stack_pop (Dirstack_state *ds)
424 {
425   assert (0 < AD_stack_height (ds));
426
427   /* operate on Active_dir.  pop and free top entry */
428   struct AD_ent *top = AD_stack_top (ds);
429   if (top->unremovable)
430     hash_free (top->unremovable);
431   obstack_blank (&ds->Active_dir, -(int) sizeof (struct AD_ent));
432 }
433
434 static void
435 AD_stack_clear (Dirstack_state *ds)
436 {
437   while (0 < AD_stack_height (ds))
438     {
439       AD_stack_pop (ds);
440     }
441 }
442
443 static Dirstack_state *
444 ds_init (void)
445 {
446   Dirstack_state *ds = xmalloc (sizeof *ds);
447   obstack_init (&ds->dir_stack);
448   obstack_init (&ds->len_stack);
449   obstack_init (&ds->Active_dir);
450   return ds;
451 }
452
453 static void
454 ds_clear (Dirstack_state *ds)
455 {
456   obstack_free (&ds->dir_stack, obstack_finish (&ds->dir_stack));
457   obstack_free (&ds->len_stack, obstack_finish (&ds->len_stack));
458   while (0 < AD_stack_height (ds))
459     AD_stack_pop (ds);
460   obstack_free (&ds->Active_dir, obstack_finish (&ds->Active_dir));
461 }
462
463 static void
464 ds_free (Dirstack_state *ds)
465 {
466   obstack_free (&ds->dir_stack, NULL);
467   obstack_free (&ds->len_stack, NULL);
468   obstack_free (&ds->Active_dir, NULL);
469   free (ds);
470 }
471
472 /* Pop the active directory (AD) stack and prepare to move `up' one level,
473    safely.  Moving `up' usually means opening `..', but when we've just
474    finished recursively processing a command-line directory argument,
475    there's nothing left on the stack, so set *FDP to AT_FDCWD in that case.
476    The idea is to return with *FDP opened on the parent directory,
477    assuming there are entries in that directory that we need to remove.
478
479    Note that we must not call opendir (or fdopendir) just yet, since
480    the caller must first remove the directory we're coming from.
481    That is because some file system implementations cache readdir
482    results at opendir time; so calling opendir, rmdir, readdir would
483    return an entry for the just-removed directory.
484
485    Whenever using chdir '..' (virtually, now, via openat), verify
486    that the post-chdir dev/ino numbers for `.' match the saved ones.
487    If any system call fails or if dev/ino don't match, then give a
488    diagnostic and longjump out.
489    Return the name (in malloc'd storage) of the
490    directory (usually now empty) from which we're coming, and which
491    corresponds to the input value of DIRP.
492
493    Finally, note that while this function's name is no longer as
494    accurate as it once was (it no longer calls chdir), it does open
495    the destination directory.  */
496 static char *
497 AD_pop_and_chdir (DIR *dirp, int *fdp, Dirstack_state *ds)
498 {
499   struct AD_ent *leaf_dir_ent = AD_stack_top(ds);
500   struct dev_ino leaf_dev_ino = leaf_dir_ent->dev_ino;
501   enum RM_status old_status = leaf_dir_ent->status;
502   struct AD_ent *top;
503
504   /* Get the name of the current (but soon to be `previous') directory
505      from the top of the stack.  */
506   char *prev_dir = top_dir (ds);
507
508   AD_stack_pop (ds);
509   pop_dir (ds);
510   top = AD_stack_top (ds);
511
512   /* If the directory we're about to leave (and try to rmdir)
513      is the one whose dev_ino is being used to detect a cycle,
514      reset cycle_check_state.dev_ino to that of the parent.
515      Otherwise, once that directory is removed, its dev_ino
516      could be reused in the creation (by some other process)
517      of a directory that this rm process would encounter,
518      which would result in a false-positive cycle indication.  */
519   CYCLE_CHECK_REFLECT_CHDIR_UP (&ds->cycle_check_state,
520                                 top->dev_ino, leaf_dev_ino);
521
522   /* Propagate any failure to parent.  */
523   UPDATE_STATUS (top->status, old_status);
524
525   assert (AD_stack_height (ds));
526
527   if (1 < AD_stack_height (ds))
528     {
529       struct stat sb;
530       int fd = openat (dirfd (dirp), "..", O_RDONLY);
531       if (closedir (dirp) != 0)
532         {
533           error (0, errno, _("FATAL: failed to close directory %s"),
534                  quote (full_filename (prev_dir)));
535           goto next_cmdline_arg;
536         }
537
538       /* The above fails with EACCES when DIRP is readable but not
539          searchable, when using Solaris' openat.  Without this openat
540          call, tests/rm2 would fail to remove directories a/2 and a/3.  */
541       if (fd < 0)
542         fd = openat (AT_FDCWD, xfull_filename (ds, "."), O_RDONLY);
543
544       if (fd < 0)
545         {
546           error (0, errno, _("FATAL: cannot open .. from %s"),
547                  quote (full_filename (prev_dir)));
548           goto next_cmdline_arg;
549         }
550
551       if (fstat (fd, &sb))
552         {
553           error (0, errno,
554                  _("FATAL: cannot ensure %s (returned to via ..) is safe"),
555                  quote (full_filename (".")));
556           goto close_and_next;
557         }
558
559       /*  Ensure that post-chdir dev/ino match the stored ones.  */
560       if ( ! SAME_INODE (sb, top->dev_ino))
561         {
562           error (0, 0, _("FATAL: directory %s changed dev/ino"),
563                  quote (full_filename (".")));
564         close_and_next:;
565           close (fd);
566
567         next_cmdline_arg:;
568           free (prev_dir);
569           longjmp (ds->current_arg_jumpbuf, 1);
570         }
571       *fdp = fd;
572     }
573   else
574     {
575       if (closedir (dirp) != 0)
576         {
577           error (0, errno, _("FATAL: failed to close directory %s"),
578                  quote (full_filename (prev_dir)));
579           goto next_cmdline_arg;
580         }
581       *fdp = AT_FDCWD;
582     }
583
584   return prev_dir;
585 }
586
587 /* Initialize *HT if it is NULL.  Return *HT.  */
588 static Hash_table *
589 AD_ensure_initialized (Hash_table **ht)
590 {
591   if (*ht == NULL)
592     {
593       *ht = hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY, NULL, hash_pjw,
594                              hash_compare_strings, hash_freer);
595       if (*ht == NULL)
596         xalloc_die ();
597     }
598
599   return *ht;
600 }
601
602 /* Initialize *HT if it is NULL.
603    Insert FILENAME into HT.  */
604 static void
605 AD_mark_helper (Hash_table **ht, char *filename)
606 {
607   void *ent = hash_insert (AD_ensure_initialized (ht), filename);
608   if (ent == NULL)
609     xalloc_die ();
610   else
611     {
612       if (ent != filename)
613         free (filename);
614     }
615 }
616
617 /* Mark FILENAME (in current directory) as unremovable.  */
618 static void
619 AD_mark_as_unremovable (Dirstack_state *ds, char const *filename)
620 {
621   AD_mark_helper (&AD_stack_top(ds)->unremovable, xstrdup (filename));
622 }
623
624 /* Mark the current directory as unremovable.  I.e., mark the entry
625    in the parent directory corresponding to `.'.
626    This happens e.g., when an opendir fails and the only name
627    the caller has conveniently at hand is `.'.  */
628 static void
629 AD_mark_current_as_unremovable (Dirstack_state *ds)
630 {
631   struct AD_ent *top = AD_stack_top (ds);
632   char *curr = top_dir (ds);
633
634   assert (1 < AD_stack_height (ds));
635
636   --top;
637   AD_mark_helper (&top->unremovable, curr);
638 }
639
640 /* Push an initial dummy entry onto the stack.
641    This will always be the bottommost entry on the stack.  */
642 static void
643 AD_push_initial (Dirstack_state *ds)
644 {
645   struct AD_ent *top;
646
647   /* Extend the stack.  */
648   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
649
650   /* Fill in the new values.  */
651   top = AD_stack_top (ds);
652   top->unremovable = NULL;
653
654   /* These should never be used.
655      Give them values that might look suspicious
656      in a debugger or in a diagnostic.  */
657   top->dev_ino.st_dev = TYPE_MAXIMUM (dev_t);
658   top->dev_ino.st_ino = TYPE_MAXIMUM (ino_t);
659 }
660
661 /* Push info about the current working directory (".") onto the
662    active directory stack.  DIR is the ./-relative name through
663    which we've just `chdir'd to this directory.  DIR_SB_FROM_PARENT
664    is the result of calling lstat on DIR from the parent of DIR.
665    Longjump out (skipping the entire command line argument we're
666    dealing with) if `fstat (FD_CWD, ...' fails or if someone has
667    replaced DIR with e.g., a symlink to some other directory.  */
668 static void
669 AD_push (int fd_cwd, Dirstack_state *ds, char const *dir,
670          struct stat const *dir_sb_from_parent)
671 {
672   struct AD_ent *top;
673
674   push_dir (ds, dir);
675
676   /* If our uses of openat are guaranteed not to
677      follow a symlink, then we can skip this check.  */
678   if (! HAVE_WORKING_O_NOFOLLOW)
679     {
680       struct stat sb;
681       if (fstat (fd_cwd, &sb) != 0)
682         {
683           error (0, errno, _("FATAL: cannot enter directory %s"),
684                  quote (full_filename (".")));
685           longjmp (ds->current_arg_jumpbuf, 1);
686         }
687
688       if ( ! SAME_INODE (sb, *dir_sb_from_parent))
689         {
690           error (0, 0,
691                  _("FATAL: just-changed-to directory %s changed dev/ino"),
692                  quote (full_filename (".")));
693           longjmp (ds->current_arg_jumpbuf, 1);
694         }
695     }
696
697   if (cycle_check (&ds->cycle_check_state, dir_sb_from_parent))
698     {
699       error (0, 0, _("\
700 WARNING: Circular directory structure.\n\
701 This almost certainly means that you have a corrupted file system.\n\
702 NOTIFY YOUR SYSTEM MANAGER.\n\
703 The following directory is part of the cycle:\n  %s\n"),
704              quote (full_filename (".")));
705       longjmp (ds->current_arg_jumpbuf, 1);
706     }
707
708   /* Extend the stack.  */
709   obstack_blank (&ds->Active_dir, sizeof (struct AD_ent));
710
711   /* The active directory stack must be one larger than the length stack.  */
712   assert (AD_stack_height (ds) ==
713           1 + obstack_object_size (&ds->len_stack) / sizeof (size_t));
714
715   /* Fill in the new values.  */
716   top = AD_stack_top (ds);
717   top->dev_ino.st_dev = dir_sb_from_parent->st_dev;
718   top->dev_ino.st_ino = dir_sb_from_parent->st_ino;
719   top->unremovable = NULL;
720 }
721
722 static inline bool
723 AD_is_removable (Dirstack_state const *ds, char const *file)
724 {
725   struct AD_ent *top = AD_stack_top (ds);
726   return ! (top->unremovable && hash_lookup (top->unremovable, file));
727 }
728
729 /* Return 1 if FILE is an unwritable non-symlink,
730    0 if it is writable or some other type of file,
731    -1 and set errno if there is some problem in determining the answer.
732    Set *BUF to the file status.
733    This is to avoid calling euidaccess when FILE is a symlink.  */
734 static int
735 write_protected_non_symlink (int fd_cwd,
736                              char const *file,
737                              Dirstack_state const *ds,
738                              struct stat *buf)
739 {
740   if (can_write_any_file ())
741     return 0;
742   if (cache_fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
743     return -1;
744   if (S_ISLNK (buf->st_mode))
745     return 0;
746   /* Here, we know FILE is not a symbolic link.  */
747
748   /* In order to be reentrant -- i.e., to avoid changing the working
749      directory, and at the same time to be able to deal with alternate
750      access control mechanisms (ACLs, xattr-style attributes) and
751      arbitrarily deep trees -- we need a function like eaccessat, i.e.,
752      like Solaris' eaccess, but fd-relative, in the spirit of openat.  */
753
754   /* In the absence of a native eaccessat function, here are some of
755      the implementation choices [#4 and #5 were suggested by Paul Eggert]:
756      1) call openat with O_WRONLY|O_NOCTTY
757         Disadvantage: may create the file and doesn't work for directory,
758         may mistakenly report `unwritable' for EROFS or ACLs even though
759         perm bits say the file is writable.
760
761      2) fake eaccessat (save_cwd, fchdir, call euidaccess, restore_cwd)
762         Disadvantage: changes working directory (not reentrant) and can't
763         work if save_cwd fails.
764
765      3) if (euidaccess (xfull_filename (file), W_OK) == 0)
766         Disadvantage: doesn't work if xfull_filename is too long.
767         Inefficient for very deep trees (O(Depth^2)).
768
769      4) If the full pathname is sufficiently short (say, less than
770         PATH_MAX or 8192 bytes, whichever is shorter):
771         use method (3) (i.e., euidaccess (xfull_filename (file), W_OK));
772         Otherwise: vfork, fchdir in the child, run euidaccess in the
773         child, then the child exits with a status that tells the parent
774         whether euidaccess succeeded.
775
776         This avoids the O(N**2) algorithm of method (3), and it also avoids
777         the failure-due-to-too-long-file-names of method (3), but it's fast
778         in the normal shallow case.  It also avoids the lack-of-reentrancy
779         and the save_cwd problems.
780         Disadvantage; it uses a process slot for very-long file names,
781         and would be very slow for hierarchies with many such files.
782
783      5) If the full file name is sufficiently short (say, less than
784         PATH_MAX or 8192 bytes, whichever is shorter):
785         use method (3) (i.e., euidaccess (xfull_filename (file), W_OK));
786         Otherwise: look just at the file bits.  Perhaps issue a warning
787         the first time this occurs.
788
789         This is like (4), except for the "Otherwise" case where it isn't as
790         "perfect" as (4) but is considerably faster.  It conforms to current
791         POSIX, and is uniformly better than what Solaris and FreeBSD do (they
792         mess up with long file names). */
793
794   {
795     /* This implements #5: */
796     size_t file_name_len
797       = obstack_object_size (&ds->dir_stack) + strlen (file);
798
799     if (MIN (PATH_MAX, 8192) <= file_name_len)
800       return ! euidaccess_stat (buf, W_OK);
801     if (euidaccess (xfull_filename (ds, file), W_OK) == 0)
802       return 0;
803     if (errno == EACCES)
804       {
805         errno = 0;
806         return 1;
807       }
808
809     /* Perhaps some other process has removed the file, or perhaps this
810        is a buggy NFS client.  */
811     return -1;
812   }
813 }
814
815 /* Prompt whether to remove FILENAME, if required via a combination of
816    the options specified by X and/or file attributes.  If the file may
817    be removed, return RM_OK.  If the user declines to remove the file,
818    return RM_USER_DECLINED.  If not ignoring missing files and we
819    cannot lstat FILENAME, then return RM_ERROR.
820
821    *PDIRENT_TYPE is the type of the directory entry; update it to DT_DIR
822    or DT_LNK as needed.  *SBUF is the file's status.
823
824    Depending on MODE, ask whether to `descend into' or to `remove' the
825    directory FILENAME.  MODE is ignored when FILENAME is not a directory.
826    Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
827    appropriate to try to remove it with rmdir (e.g. recursive mode).
828    Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.  */
829 static enum RM_status
830 prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
831         int *pdirent_type, struct stat *sbuf,
832         struct rm_options const *x, enum Prompt_action mode,
833         Ternary *is_empty)
834 {
835   int write_protected = 0;
836   int dirent_type = *pdirent_type;
837
838   *is_empty = T_UNKNOWN;
839
840   if (x->interactive == RMI_NEVER)
841     return RM_OK;
842
843   int wp_errno = 0;
844
845   if (!x->ignore_missing_files
846       && ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
847       && dirent_type != DT_LNK)
848     {
849       write_protected = write_protected_non_symlink (fd_cwd, filename, ds, sbuf);
850       wp_errno = errno;
851     }
852
853   if (write_protected || x->interactive == RMI_ALWAYS)
854     {
855       if (0 <= write_protected && dirent_type == DT_UNKNOWN)
856         {
857           if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
858             {
859               if (S_ISLNK (sbuf->st_mode))
860                 dirent_type = DT_LNK;
861               else if (S_ISDIR (sbuf->st_mode))
862                 dirent_type = DT_DIR;
863               /* Otherwise it doesn't matter, so leave it DT_UNKNOWN.  */
864               *pdirent_type = dirent_type;
865             }
866           else
867             {
868               /* This happens, e.g., with `rm '''.  */
869               write_protected = -1;
870               wp_errno = errno;
871             }
872         }
873
874       if (0 <= write_protected)
875         switch (dirent_type)
876           {
877           case DT_LNK:
878             /* Using permissions doesn't make sense for symlinks.  */
879             if (x->interactive != RMI_ALWAYS)
880               return RM_OK;
881             break;
882
883           case DT_DIR:
884             if (!x->recursive)
885               {
886                 write_protected = -1;
887                 wp_errno = EISDIR;
888               }
889             break;
890           }
891
892       char const *quoted_name = quote (full_filename (filename));
893
894       if (write_protected < 0)
895         {
896           error (0, wp_errno, _("cannot remove %s"), quoted_name);
897           return RM_ERROR;
898         }
899
900       /* Issue the prompt.  */
901       /* FIXME: use a variant of error (instead of fprintf) that doesn't
902          append a newline.  Then we won't have to declare program_name in
903          this file.  */
904       if (dirent_type == DT_DIR
905           && mode == PA_DESCEND_INTO_DIR
906           && ((*is_empty = (is_empty_dir (fd_cwd, filename) ? T_YES : T_NO))
907               == T_NO))
908         fprintf (stderr,
909                  (write_protected
910                   ? _("%s: descend into write-protected directory %s? ")
911                   : _("%s: descend into directory %s? ")),
912                  program_name, quoted_name);
913       else
914         {
915           if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
916             {
917               error (0, errno, _("cannot remove %s"), quoted_name);
918               return RM_ERROR;
919             }
920
921           /* TRANSLATORS: You may find it more convenient to translate
922              the equivalent of _("%s: remove %s (write-protected) %s? ").
923              It should avoid grammatical problems with the output
924              of file_type.  */
925           fprintf (stderr,
926                    (write_protected
927                     ? _("%s: remove write-protected %s %s? ")
928                     : _("%s: remove %s %s? ")),
929                    program_name, file_type (sbuf), quoted_name);
930         }
931
932       if (!yesno ())
933         return RM_USER_DECLINED;
934     }
935   return RM_OK;
936 }
937
938 /* Return true if FILENAME is a directory (and not a symlink to a directory).
939    Otherwise, including the case in which lstat fails, return false.
940    *ST is FILENAME's tstatus.
941    Do not modify errno.  */
942 static inline bool
943 is_dir_lstat (int fd_cwd, char const *filename, struct stat *st)
944 {
945   int saved_errno = errno;
946   bool is_dir =
947     (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
948      && S_ISDIR (st->st_mode));
949   errno = saved_errno;
950   return is_dir;
951 }
952
953 /* Return true if FILENAME is a non-directory.
954    Otherwise, including the case in which lstat fails, return false.
955    *ST is FILENAME's tstatus.
956    Do not modify errno.  */
957 static inline bool
958 is_nondir_lstat (int fd_cwd, char const *filename, struct stat *st)
959 {
960   int saved_errno = errno;
961   bool is_non_dir =
962     (cache_fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW) == 0
963      && !S_ISDIR (st->st_mode));
964   errno = saved_errno;
965   return is_non_dir;
966 }
967
968 #define DO_UNLINK(Fd_cwd, Filename, X)                                  \
969   do                                                                    \
970     {                                                                   \
971       if (unlinkat (Fd_cwd, Filename, 0) == 0)                          \
972         {                                                               \
973           if ((X)->verbose)                                             \
974             printf (_("removed %s\n"), quote (full_filename (Filename))); \
975           return RM_OK;                                                 \
976         }                                                               \
977                                                                         \
978       if (ignorable_missing (X, errno))                                 \
979         return RM_OK;                                                   \
980     }                                                                   \
981   while (0)
982
983 #define DO_RMDIR(Fd_cwd, Filename, X)                   \
984   do                                                    \
985     {                                                   \
986       if (unlinkat (Fd_cwd, Filename, AT_REMOVEDIR) == 0) /* rmdir */ \
987         {                                               \
988           if ((X)->verbose)                             \
989             printf (_("removed directory: %s\n"),       \
990                     quote (full_filename (Filename)));  \
991           return RM_OK;                                 \
992         }                                               \
993                                                         \
994       if (ignorable_missing (X, errno))                 \
995         return RM_OK;                                   \
996                                                         \
997       if (errno == ENOTEMPTY || errno == EEXIST)        \
998         return RM_NONEMPTY_DIR;                         \
999     }                                                   \
1000   while (0)
1001
1002 /* When a function like unlink, rmdir, or fstatat fails with an errno
1003    value of ERRNUM, return true if the specified file system object
1004    is guaranteed not to exist;  otherwise, return false.  */
1005 static inline bool
1006 nonexistent_file_errno (int errnum)
1007 {
1008   /* Do not include ELOOP here, since the specified file may indeed
1009      exist, but be (in)accessible only via too long a symlink chain.
1010      Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
1011      if the "..." part expands to a long enough sequence of "./"s,
1012      even though ./foo does indeed exist.  */
1013
1014   switch (errnum)
1015     {
1016     case ENOENT:
1017     case ENOTDIR:
1018       return true;
1019     default:
1020       return false;
1021     }
1022 }
1023
1024 /* Encapsulate the test for whether the errno value, ERRNUM, is ignorable.  */
1025 static inline bool
1026 ignorable_missing (struct rm_options const *x, int errnum)
1027 {
1028   return x->ignore_missing_files && nonexistent_file_errno (errnum);
1029 }
1030
1031 /* Remove the file or directory specified by FILENAME.
1032    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
1033    But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */
1034
1035 static enum RM_status
1036 remove_entry (int fd_cwd, Dirstack_state const *ds, char const *filename,
1037               int dirent_type_arg, struct stat *st,
1038               struct rm_options const *x)
1039 {
1040   Ternary is_empty_directory;
1041   enum RM_status s = prompt (fd_cwd, ds, filename, &dirent_type_arg, st, x,
1042                              PA_DESCEND_INTO_DIR,
1043                              &is_empty_directory);
1044   int dirent_type = dirent_type_arg;
1045   if (s != RM_OK)
1046     return s;
1047
1048   /* Why bother with the following if/else block?  Because on systems with
1049      an unlink function that *can* unlink directories, we must determine the
1050      type of each entry before removing it.  Otherwise, we'd risk unlinking
1051      an entire directory tree simply by unlinking a single directory;  then
1052      all the storage associated with that hierarchy would not be freed until
1053      the next fsck.  Not nice.  To avoid that, on such slightly losing
1054      systems, we need to call lstat to determine the type of each entry,
1055      and that represents extra overhead that -- it turns out -- we can
1056      avoid on non-losing systems, since there, unlink will never remove
1057      a directory.  Also, on systems where unlink may unlink directories,
1058      we're forced to allow a race condition: we lstat a non-directory, then
1059      go to unlink it, but in the mean time, a malicious someone could have
1060      replaced it with a directory.  */
1061
1062   if (cannot_unlink_dir ())
1063     {
1064       if (dirent_type == DT_DIR && ! x->recursive)
1065         {
1066           error (0, EISDIR, _("cannot remove %s"),
1067                  quote (full_filename (filename)));
1068           return RM_ERROR;
1069         }
1070
1071       /* is_empty_directory is set iff it's ok to use rmdir.
1072          Note that it's set only in interactive mode -- in which case it's
1073          an optimization that arranges so that the user is asked just
1074          once whether to remove the directory.  */
1075       if (is_empty_directory == T_YES)
1076         DO_RMDIR (fd_cwd, filename, x);
1077
1078       /* If we happen to know that FILENAME is a directory, return now
1079          and let the caller remove it -- this saves the overhead of a failed
1080          unlink call.  If FILENAME is a command-line argument, then
1081          DIRENT_TYPE is DT_UNKNOWN so we'll first try to unlink it.
1082          Using unlink here is ok, because it cannot remove a
1083          directory.  */
1084       if (dirent_type == DT_DIR)
1085         return RM_NONEMPTY_DIR;
1086
1087       DO_UNLINK (fd_cwd, filename, x);
1088
1089       /* Upon a failed attempt to unlink a directory, most non-Linux systems
1090          set errno to the POSIX-required value EPERM.  In that case, change
1091          errno to EISDIR so that we emit a better diagnostic.  */
1092       if (! x->recursive && errno == EPERM && is_dir_lstat (fd_cwd,
1093                                                             filename, st))
1094         errno = EISDIR;
1095
1096       if (! x->recursive
1097           || (cache_stat_ok (st) && !S_ISDIR (st->st_mode))
1098           || ((errno == EACCES || errno == EPERM)
1099               && is_nondir_lstat (fd_cwd, filename, st))
1100           )
1101         {
1102           if (ignorable_missing (x, errno))
1103             return RM_OK;
1104
1105           /* Either --recursive is not in effect, or the file cannot be a
1106              directory.  Report the unlink problem and fail.  */
1107           error (0, errno, _("cannot remove %s"),
1108                  quote (full_filename (filename)));
1109           return RM_ERROR;
1110         }
1111       assert (!cache_stat_ok (st) || S_ISDIR (st->st_mode));
1112     }
1113   else
1114     {
1115       /* If we don't already know whether FILENAME is a directory,
1116          find out now.  Then, if it's a non-directory, we can use
1117          unlink on it.  */
1118
1119       if (dirent_type == DT_UNKNOWN)
1120         {
1121           if (fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW))
1122             {
1123               if (ignorable_missing (x, errno))
1124                 return RM_OK;
1125
1126               error (0, errno, _("cannot remove %s"),
1127                      quote (full_filename (filename)));
1128               return RM_ERROR;
1129             }
1130
1131           if (S_ISDIR (st->st_mode))
1132             dirent_type = DT_DIR;
1133         }
1134
1135       if (dirent_type != DT_DIR)
1136         {
1137           /* At this point, barring race conditions, FILENAME is known
1138              to be a non-directory, so it's ok to try to unlink it.  */
1139           DO_UNLINK (fd_cwd, filename, x);
1140
1141           /* unlink failed with some other error code.  report it.  */
1142           error (0, errno, _("cannot remove %s"),
1143                  quote (full_filename (filename)));
1144           return RM_ERROR;
1145         }
1146
1147       if (! x->recursive)
1148         {
1149           error (0, EISDIR, _("cannot remove %s"),
1150                  quote (full_filename (filename)));
1151           return RM_ERROR;
1152         }
1153
1154       if (is_empty_directory == T_YES)
1155         {
1156           DO_RMDIR (fd_cwd, filename, x);
1157           /* Don't diagnose any failure here.
1158              It'll be detected when the caller tries another way.  */
1159         }
1160     }
1161
1162   return RM_NONEMPTY_DIR;
1163 }
1164
1165 /* Given FD_CWD, the file descriptor for an open directory,
1166    open its subdirectory F (F is already `known' to be a directory,
1167    so if it is no longer one, someone is playing games), return a DIR*
1168    pointer for F, and put F's `stat' data in *SUBDIR_SB.
1169    Upon failure give a diagnostic and return NULL.
1170    If PREV_ERRNO is nonzero, it is the errno value from a preceding failed
1171    unlink- or rmdir-like system call -- use that value instead of ENOTDIR
1172    if an opened file turns out not to be a directory.  This is important
1173    when the preceding non-dir-unlink failed due to e.g., EPERM or EACCES.
1174    The caller must use a nonnnull CWD_ERRNO the first
1175    time this function is called for each command-line-specified directory.
1176    If CWD_ERRNO is not null, set *CWD_ERRNO to the appropriate error number
1177    if this function fails to restore the initial working directory.
1178    If it is null, report an error and exit if the working directory
1179    isn't restored.  */
1180 static DIR *
1181 fd_to_subdirp (int fd_cwd, char const *f,
1182                int prev_errno,
1183                struct stat *subdir_sb,
1184                int *cwd_errno ATTRIBUTE_UNUSED)
1185 {
1186   int open_flags = O_RDONLY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK;
1187   int fd_sub = openat_permissive (fd_cwd, f, open_flags, 0, cwd_errno);
1188   int saved_errno;
1189
1190   /* Record dev/ino of F.  We may compare them against saved values
1191      to thwart any attempt to subvert the traversal.  They are also used
1192      to detect directory cycles.  */
1193   if (fd_sub < 0)
1194     return NULL;
1195   else if (fstat (fd_sub, subdir_sb) != 0)
1196     saved_errno = errno;
1197   else if (S_ISDIR (subdir_sb->st_mode))
1198     {
1199       DIR *subdir_dirp = fdopendir (fd_sub);
1200       if (subdir_dirp)
1201         return subdir_dirp;
1202       saved_errno = errno;
1203     }
1204   else
1205     saved_errno = (prev_errno ? prev_errno : ENOTDIR);
1206
1207   close (fd_sub);
1208   errno = saved_errno;
1209   return NULL;
1210 }
1211
1212 /* Remove entries in the directory open on DIRP
1213    Upon finding a directory that is both non-empty and that can be chdir'd
1214    into, return RM_OK and set *SUBDIR and fill in SUBDIR_SB, where
1215    SUBDIR is the malloc'd name of the subdirectory if the chdir succeeded,
1216    NULL otherwise (e.g., if opendir failed or if there was no subdirectory).
1217    Likewise, SUBDIR_SB is the result of calling lstat on SUBDIR.
1218    Return RM_OK if all entries are removed.  Return RM_ERROR if any
1219    entry cannot be removed.  Otherwise, return RM_USER_DECLINED if
1220    the user declines to remove at least one entry.  Remove as much as
1221    possible, continuing even if we fail to remove some entries.  */
1222 static enum RM_status
1223 remove_cwd_entries (DIR **dirp,
1224                     Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
1225                     struct rm_options const *x)
1226 {
1227   struct AD_ent *top = AD_stack_top (ds);
1228   enum RM_status status = top->status;
1229   size_t n_unlinked_since_opendir_or_last_rewind = 0;
1230
1231   assert (VALID_STATUS (status));
1232   *subdir = NULL;
1233
1234   while (1)
1235     {
1236       struct dirent const *dp;
1237       enum RM_status tmp_status;
1238       const char *f;
1239
1240       /* Set errno to zero so we can distinguish between a readdir failure
1241          and when readdir simply finds that there are no more entries.  */
1242       errno = 0;
1243       dp = readdir_ignoring_dot_and_dotdot (*dirp);
1244       if (dp == NULL)
1245         {
1246           if (errno)
1247             {
1248               /* fall through */
1249             }
1250           else if (NEED_REWIND (n_unlinked_since_opendir_or_last_rewind))
1251             {
1252               /* Call rewinddir if we've called unlink or rmdir so many times
1253                  (since the opendir or the previous rewinddir) that this
1254                  NULL-return may be the symptom of a buggy readdir.  */
1255               rewinddir (*dirp);
1256               n_unlinked_since_opendir_or_last_rewind = 0;
1257               continue;
1258             }
1259           break;
1260         }
1261
1262       f = dp->d_name;
1263
1264       /* Skip files we've already tried/failed to remove.  */
1265       if ( ! AD_is_removable (ds, f))
1266         continue;
1267
1268       /* Pass dp->d_type info to remove_entry so the non-glibc
1269          case can decide whether to use unlink or chdir.
1270          Systems without the d_type member will have to endure
1271          the performance hit of first calling lstat F. */
1272       cache_stat_init (subdir_sb);
1273       tmp_status = remove_entry (dirfd (*dirp), ds, f,
1274                                  D_TYPE (dp), subdir_sb, x);
1275       switch (tmp_status)
1276         {
1277         case RM_OK:
1278           /* Count how many files we've unlinked since the initial
1279              opendir or the last rewinddir.  On buggy systems, if you
1280              remove too many, readdir returns NULL even though there
1281              remain unprocessed directory entries.  */
1282           ++n_unlinked_since_opendir_or_last_rewind;
1283           break;
1284
1285         case RM_ERROR:
1286         case RM_USER_DECLINED:
1287           AD_mark_as_unremovable (ds, f);
1288           UPDATE_STATUS (status, tmp_status);
1289           break;
1290
1291         case RM_NONEMPTY_DIR:
1292           {
1293             DIR *subdir_dirp = fd_to_subdirp (dirfd (*dirp), f,
1294                                               errno, subdir_sb, NULL);
1295             if (subdir_dirp == NULL)
1296               {
1297                 status = RM_ERROR;
1298
1299                 /* CAUTION: this test and diagnostic are identical to
1300                    those following the other use of fd_to_subdirp.  */
1301                 if (ignorable_missing (x, errno))
1302                   {
1303                     /* With -f, don't report "file not found".  */
1304                   }
1305                 else
1306                   {
1307                     /* Upon fd_to_subdirp failure, try to remove F directly,
1308                        in case it's just an empty directory.  */
1309                     int saved_errno = errno;
1310                     if (unlinkat (dirfd (*dirp), f, AT_REMOVEDIR) == 0)
1311                       status = RM_OK;
1312                     else
1313                       error (0, saved_errno,
1314                              _("cannot remove %s"), quote (full_filename (f)));
1315                   }
1316
1317                 if (status == RM_ERROR)
1318                   AD_mark_as_unremovable (ds, f);
1319                 break;
1320               }
1321
1322             *subdir = xstrdup (f);
1323             if (closedir (*dirp) != 0)
1324               {
1325                 error (0, 0, _("failed to close directory %s"),
1326                        quote (full_filename (".")));
1327                 status = RM_ERROR;
1328               }
1329             *dirp = subdir_dirp;
1330
1331             break;
1332           }
1333         }
1334
1335       /* Record status for this directory.  */
1336       UPDATE_STATUS (top->status, status);
1337
1338       if (*subdir)
1339         break;
1340     }
1341
1342   /* Ensure that *dirp is not NULL and that its file descriptor is valid.  */
1343   assert (*dirp != NULL);
1344   assert (0 <= fcntl (dirfd (*dirp), F_GETFD));
1345
1346   return status;
1347 }
1348
1349 /* Do this after each call to AD_push or AD_push_initial.
1350    Because the status = RM_OK bit is too remove-specific to
1351    go into the general-purpose AD_* package.  */
1352 #define AD_INIT_OTHER_MEMBERS()                 \
1353   do                                            \
1354     {                                           \
1355       AD_stack_top(ds)->status = RM_OK;         \
1356     }                                           \
1357   while (0)
1358
1359 /*  Remove the hierarchy rooted at DIR.
1360     Do that by changing into DIR, then removing its contents, then
1361     returning to the original working directory and removing DIR itself.
1362     Don't use recursion.  Be careful when using chdir ".." that we
1363     return to the same directory from which we came, if necessary.
1364     Return an RM_status value to indicate success or failure.  */
1365
1366 static enum RM_status
1367 remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir,
1368             struct stat *dir_st,
1369             struct rm_options const *x, int *cwd_errno)
1370 {
1371   enum RM_status status;
1372   dev_t current_dev = dir_st->st_dev;
1373
1374   /* There is a race condition in that an attacker could replace the nonempty
1375      directory, DIR, with a symlink between the preceding call to rmdir
1376      (unlinkat, in our caller) and fd_to_subdirp's openat call.  But on most
1377      systems, even those without openat, this isn't a problem, since we ensure
1378      that opening a symlink will fail, when that is possible.  Otherwise,
1379      fd_to_subdirp's fstat, along with the `fstat' and the dev/ino
1380      comparison in AD_push ensure that we detect it and fail.  */
1381
1382   DIR *dirp = fd_to_subdirp (fd_cwd, dir, 0, dir_st, cwd_errno);
1383
1384   if (dirp == NULL)
1385     {
1386       /* CAUTION: this test and diagnostic are identical to
1387          those following the other use of fd_to_subdirp.  */
1388       if (ignorable_missing (x, errno))
1389         {
1390           /* With -f, don't report "file not found".  */
1391         }
1392       else
1393         {
1394           /* Upon fd_to_subdirp failure, try to remove DIR directly,
1395              in case it's just an empty directory.  */
1396           int saved_errno = errno;
1397           if (unlinkat (fd_cwd, dir, AT_REMOVEDIR) == 0)
1398             return RM_OK;
1399
1400           error (0, saved_errno,
1401                  _("cannot remove %s"), quote (full_filename (dir)));
1402         }
1403
1404       return RM_ERROR;
1405     }
1406
1407   if (ROOT_DEV_INO_CHECK (x->root_dev_ino, dir_st))
1408     {
1409       ROOT_DEV_INO_WARN (full_filename (dir));
1410       status = RM_ERROR;
1411       goto closedir_and_return;
1412     }
1413
1414   AD_push (dirfd (dirp), ds, dir, dir_st);
1415   AD_INIT_OTHER_MEMBERS ();
1416
1417   status = RM_OK;
1418
1419   while (1)
1420     {
1421       char *subdir = NULL;
1422       struct stat subdir_sb;
1423       enum RM_status tmp_status;
1424
1425       tmp_status = remove_cwd_entries (&dirp, ds, &subdir, &subdir_sb, x);
1426
1427       if (tmp_status != RM_OK)
1428         {
1429           UPDATE_STATUS (status, tmp_status);
1430           AD_mark_current_as_unremovable (ds);
1431         }
1432       if (subdir)
1433         {
1434           if ( ! x->one_file_system
1435                || subdir_sb.st_dev == current_dev)
1436             {
1437               AD_push (dirfd (dirp), ds, subdir, &subdir_sb);
1438               AD_INIT_OTHER_MEMBERS ();
1439               free (subdir);
1440               continue;
1441             }
1442
1443           /* Here, --one-file-system is in effect, and with remove_cwd_entries'
1444              traversal into the current directory, (known as SUBDIR, from ..),
1445              DIRP's device number is different from CURRENT_DEV.  Arrange not
1446              to do anything more with this hierarchy.  */
1447           error (0, 0, _("skipping %s, since it's on a different device"),
1448                  quote (full_filename (subdir)));
1449           free (subdir);
1450           AD_mark_current_as_unremovable (ds);
1451           tmp_status = RM_ERROR;
1452           UPDATE_STATUS (status, tmp_status);
1453         }
1454
1455       /* Execution reaches this point when we've removed the last
1456          removable entry from the current directory -- or, with
1457          --one-file-system, when the current directory is on a
1458          different file system.  */
1459       {
1460         int fd;
1461         /* The name of the directory that we have just processed,
1462            nominally removing all of its contents.  */
1463         char *empty_dir = AD_pop_and_chdir (dirp, &fd, ds);
1464         dirp = NULL;
1465         assert (fd != AT_FDCWD || AD_stack_height (ds) == 1);
1466
1467         /* Try to remove EMPTY_DIR only if remove_cwd_entries succeeded.  */
1468         if (tmp_status == RM_OK)
1469           {
1470             struct stat empty_st;
1471             Ternary is_empty;
1472             int dirent_type = DT_DIR;
1473             enum RM_status s = prompt (fd, ds, empty_dir, &dirent_type,
1474                                        cache_stat_init (&empty_st), x,
1475                                        PA_REMOVE_DIR, &is_empty);
1476
1477             if (s != RM_OK)
1478               {
1479                 free (empty_dir);
1480                 status = s;
1481                 if (fd != AT_FDCWD)
1482                   close (fd);
1483                 goto closedir_and_return;
1484               }
1485
1486             if (unlinkat (fd, empty_dir, AT_REMOVEDIR) == 0)
1487               {
1488                 if (x->verbose)
1489                   printf (_("removed directory: %s\n"),
1490                           quote (full_filename (empty_dir)));
1491               }
1492             else
1493               {
1494                 error (0, errno, _("cannot remove directory %s"),
1495                        quote (full_filename (empty_dir)));
1496                 AD_mark_as_unremovable (ds, empty_dir);
1497                 status = RM_ERROR;
1498                 UPDATE_STATUS (AD_stack_top(ds)->status, status);
1499               }
1500           }
1501
1502         free (empty_dir);
1503
1504         if (fd == AT_FDCWD)
1505           break;
1506
1507         dirp = fdopendir (fd);
1508         if (dirp == NULL)
1509           {
1510             error (0, errno, _("FATAL: cannot return to .. from %s"),
1511                    quote (full_filename (".")));
1512             close (fd);
1513             longjmp (ds->current_arg_jumpbuf, 1);
1514           }
1515       }
1516     }
1517
1518   /* If the first/final hash table of unremovable entries was used,
1519      free it here.  */
1520   AD_stack_pop (ds);
1521
1522  closedir_and_return:;
1523   if (dirp != NULL && closedir (dirp) != 0)
1524     {
1525       error (0, 0, _("failed to close directory %s"),
1526              quote (full_filename (".")));
1527       status = RM_ERROR;
1528     }
1529
1530   return status;
1531 }
1532
1533 /* Remove the file or directory specified by FILENAME.
1534    Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.  */
1535
1536 static enum RM_status
1537 rm_1 (Dirstack_state *ds, char const *filename,
1538       struct rm_options const *x, int *cwd_errno)
1539 {
1540   char const *base = last_component (filename);
1541   if (dot_or_dotdot (base))
1542     {
1543       error (0, 0, _(base == filename
1544                      ? "cannot remove directory %s"
1545                      : "cannot remove %s directory %s"),
1546              quote_n (0, base), quote_n (1, filename));
1547       return RM_ERROR;
1548     }
1549
1550   struct stat st;
1551   cache_stat_init (&st);
1552   cycle_check_init (&ds->cycle_check_state);
1553   if (x->root_dev_ino)
1554     {
1555       if (cache_fstatat (AT_FDCWD, filename, &st, AT_SYMLINK_NOFOLLOW) != 0)
1556         {
1557           if (ignorable_missing (x, errno))
1558             return RM_OK;
1559           error (0, errno, _("cannot remove %s"), quote (filename));
1560           return RM_ERROR;
1561         }
1562       if (SAME_INODE (st, *(x->root_dev_ino)))
1563         {
1564           error (0, 0, _("cannot remove root directory %s"), quote (filename));
1565           return RM_ERROR;
1566         }
1567     }
1568
1569   AD_push_initial (ds);
1570   AD_INIT_OTHER_MEMBERS ();
1571
1572   enum RM_status status = remove_entry (AT_FDCWD, ds, filename,
1573                                         DT_UNKNOWN, &st, x);
1574   if (status == RM_NONEMPTY_DIR)
1575     {
1576       /* In the event that remove_dir->remove_cwd_entries detects
1577          a directory cycle, arrange to fail, give up on this FILE, but
1578          continue on with any other arguments.  */
1579       if (setjmp (ds->current_arg_jumpbuf))
1580         status = RM_ERROR;
1581       else
1582         status = remove_dir (AT_FDCWD, ds, filename, &st, x, cwd_errno);
1583
1584       AD_stack_clear (ds);
1585     }
1586
1587   ds_clear (ds);
1588   return status;
1589 }
1590
1591 /* Remove all files and/or directories specified by N_FILES and FILE.
1592    Apply the options in X.  */
1593 extern enum RM_status
1594 rm (size_t n_files, char const *const *file, struct rm_options const *x)
1595 {
1596   enum RM_status status = RM_OK;
1597   Dirstack_state *ds = ds_init ();
1598   int cwd_errno = 0;
1599   size_t i;
1600
1601   for (i = 0; i < n_files; i++)
1602     {
1603       if (cwd_errno && IS_RELATIVE_FILE_NAME (file[i]))
1604         {
1605           error (0, 0, _("cannot remove relative-named %s"), quote (file[i]));
1606           status = RM_ERROR;
1607         }
1608       else
1609         {
1610           enum RM_status s = rm_1 (ds, file[i], x, &cwd_errno);
1611           assert (VALID_STATUS (s));
1612           UPDATE_STATUS (status, s);
1613         }
1614     }
1615
1616   if (x->require_restore_cwd && cwd_errno)
1617     {
1618       error (0, cwd_errno,
1619              _("cannot restore current working directory"));
1620       status = RM_ERROR;
1621     }
1622
1623   ds_free (ds);
1624
1625   return status;
1626 }