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