]> pd.if.org Git - zpackage/blobdiff - zpm-syncfs.c
add contents action to zpm repo
[zpackage] / zpm-syncfs.c
index 06e5d350458f7e032058e7dfb71d70925ea3b8a3..3c0eebb0ff84bc43175d528f13e08c79e0514ce6 100644 (file)
@@ -628,15 +628,6 @@ static int remove_files(void *f, int ncols, char **vals, char **cols) {
                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);
@@ -651,12 +642,35 @@ static int remove_files(void *f, int ncols, char **vals, char **cols) {
                }
        }
 
+       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 %s: %s", dest, strerror(errno));
                }
@@ -707,6 +721,17 @@ static int set_md(struct config *conf, struct nitem *item) {
                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);
@@ -717,13 +742,6 @@ static int set_md(struct config *conf, struct nitem *item) {
                }
        }
 
-       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) {
@@ -800,16 +818,11 @@ static int install(struct config *conf, struct nitem *item, unsigned int flags)
                }
        }
 
-       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);
@@ -819,6 +832,17 @@ static int install(struct config *conf, struct nitem *item, unsigned int flags)
        }
 
        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;
        }