void ensure_pathname_nonexisting(const char *pathname) { pid_t pid; const char *u; u = path_skip_slash_dotslash(pathname); assert(*u); debug(dbg_eachfile,"ensure_pathname_nonexisting `%s'",pathname); if (!rmdir(pathname)) return; /* Deleted it OK, it was a directory. */ if (errno == ENOENT || errno == ELOOP) return; if (errno == ENOTDIR) { /* Either it's a file, or one of the path components is. If one * of the path components is this will fail again ... */ if (secure_unlink(pathname) == 0) return; /* OK, it was. */ if (errno == ENOTDIR) return; } if (errno != ENOTEMPTY && errno != EEXIST) { /* Huh? */ ohshite(_("unable to securely remove '%.255s'"), pathname); } pid = subproc_fork(); if (pid == 0) { execlp(RM, "rm", "-rf", "--", pathname, NULL); ohshite(_("unable to execute %s (%s)"), _("rm command for cleanup"), RM); } debug(dbg_eachfile,"ensure_pathname_nonexisting running rm -rf"); subproc_wait_check(pid, "rm cleanup", 0); }
/** * Securely remove a pathname. * * This is a secure version of remove(3) using secure_unlink() instead of * unlink(2). * * @retval 0 On success. * @retval -1 On failure, just like unlink(2) & rmdir(2). */ int secure_remove(const char *pathname) { int rc, e; if (!rmdir(pathname)) { debug(dbg_eachfiledetail, "secure_remove '%s' rmdir OK", pathname); return 0; } if (errno != ENOTDIR) { e = errno; debug(dbg_eachfiledetail, "secure_remove '%s' rmdir %s", pathname, strerror(e)); errno = e; return -1; } rc = secure_unlink(pathname); e = errno; debug(dbg_eachfiledetail, "secure_remove '%s' unlink %s", pathname, rc ? strerror(e) : "OK"); errno = e; return rc; }