return 0;
}
- if (lstat(dest, &st) == -1) {
- return seterror(conf,"can't stat");
- }
-
- if (S_ISDIR(st.st_mode)) {
- flags = AT_REMOVEDIR;
- }
- /* TODO check that expected filetype matches actual filetype */
-
if (conf->verbose) {
if (conf->progress == 2) {
fprintf(stderr, "%s(%s)\n", flags ? "rmdir" : "unlink", dest);
}
}
+ errno = 0;
+
+ if (lstat(dest, &st) == -1) {
+ switch (errno) {
+ case ENOENT:
+ /* TODO chatter if verbose */
+ break;
+ default:
+ return seterror(conf, "can't stat %s: %s", dest, strerror(errno));
+ }
+ return 0;
+ }
+
+ if (S_ISDIR(st.st_mode)) {
+ flags = AT_REMOVEDIR;
+ }
+ /* TODO check that expected filetype matches actual filetype */
+
+
errno = 0;
if (unlinkat(AT_FDCWD, dest, flags) == -1) {
switch (errno) {
case ENOENT:
break;
+ case ENOTEMPTY: /* fall through */
+ case EEXIST:
+ /* TODO chatter, or possibly require */
+ break;
default:
- return seterror(conf, "can't unlink");
+ return seterror(conf, "can't unlink %s: %s", dest, strerror(errno));
}
}
return success;
}
+ if (conf->setuser && conf->setgroup) {
+ rv = lchown(item->dest, item->uid, item->gid);
+ if (rv == -1) {
+ setsyserr(conf, "can't lchown %s", item->dest);
+ return conf->errabort;
+ }
+ }
+
+ /* have to chmod after the chown, setuid bits may (and will)
+ * be cleared after a chown
+ */
/* can't chmod a symlink */
if (item->ftype != 'l') {
rv = chmod(item->dest, item->mode);
}
}
- if (conf->setuser && conf->setgroup) {
- rv = lchown(item->dest, item->uid, item->gid);
- if (rv == -1) {
- setsyserr(conf, "can't lchown %s", item->dest);
- return conf->errabort;
- }
- }
rv = utimensat(AT_FDCWD, item->dest, item->times, AT_SYMLINK_NOFOLLOW);
if (rv == -1) {
}
}
- if (item->ftype == 'r') {
- rv = zpm_extract(source, item->hash, item->dest, item->mode);
- if (rv == 0) {
- seterror(conf, "can't extract %s", item->dest);
- return failure;
- }
- return success;
- }
-
+ errno = 0;
switch (item->ftype) {
+ case 'r': rv = zpm_extract(source, item->hash, item->dest, item->mode);
+ if (rv == 0) rv = -1;
+ break;
case 'd': rv = mkdir(item->dest, item->mode);
break;
case 'l': rv = symlink(item->target, item->dest);
}
if (rv == -1) {
+ switch (item->ftype) {
+ case 'r':
+ seterror(conf, "can't extract %s", item->dest);
+ break;
+ case 'd':
+ setsyserr(conf, "install mkdir(\"%s\") failed", item->dest);
+ break;
+ case 'l':
+ setsyserr(conf, "install symlink(\"%s\") failed", item->dest);
+ break;
+ }
setsyserr(conf, "installing %s failed", item->dest);
return failure;
}
fprintf(stderr, "file ops: %d\n", conf.ops_total);
if (conf.ops_remove > 0) {
if (conf.verbose) {
- fprintf(stderr, "removing %d files\n", conf.ops_remove);
+ fprintf(stderr, "removing %d file%s\n", conf.ops_remove, conf.ops_remove > 0 ? "s" : "");
}
conf.reverse = 1;
conf.ops_completed = 0;
if (conf.ops_update > 0) {
if (conf.verbose) {
- fprintf(stderr, "updating %d files\n", conf.ops_update);
+ fprintf(stderr, "updating %d file%s\n", conf.ops_update, conf.ops_update > 0 ? "s" : "");
}
conf.reverse = 0;
conf.ops_completed = 0;
if (conf.ops_install > 0) {
if (conf.verbose) {
- fprintf(stderr, "installing %d files\n", conf.ops_install);
+ fprintf(stderr, "installing %d file%s\n", conf.ops_install, conf.ops_install > 0 ? "s" : "");
}
conf.reverse = 0;
conf.ops_completed = 0;