master xplshn/aruu / shared / libutil / rm.c
 1/* See LICENSE file for copyright and license details. */
 2#include <sys/stat.h>
 3
 4#include <errno.h>
 5#include <fcntl.h>
 6#include <stdio.h>
 7#include <unistd.h>
 8
 9#include "../fs.h"
10#include "../util.h"
11
12int rm_status = 0;
13
14void
15rm(int dirfd, const char *name, struct stat *st, void *data, struct recursor *r)
16{
17  int quiet, ask, write, flags, ignore;
18
19  (void)data;
20
21  ignore = r->flags & IGNORE;
22  quiet  = r->flags & SILENT;
23  ask    = r->flags & CONFIRM;
24  write  = S_ISLNK(st->st_mode) || faccessat(dirfd, name, W_OK, 0) == 0;
25  flags  = 0;
26
27  if (S_ISDIR(st->st_mode) && r->maxdepth) {
28    errno = EISDIR;
29    goto err;
30  }
31
32  if (!quiet && ((!write && isatty(0)) || ask)) {
33    if (!confirm("remove file '%s'? ", r->path))
34      return;
35  }
36
37  if (S_ISDIR(st->st_mode)) {
38    flags = AT_REMOVEDIR;
39    recurse(dirfd, name, NULL, r);
40  }
41
42  if (unlinkat(dirfd, name, flags) < 0)
43    goto err;
44  return;
45
46err:
47  if (!ignore) {
48    weprintf("cannot remove '%s':", r->path);
49    rm_status = 1;
50  }
51}