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}