]> pd.if.org Git - zpackage/commitdiff
improve syncfs dry-run output
authorNathan Wagner <nw@hydaspes.if.org>
Wed, 17 Oct 2018 10:08:32 +0000 (10:08 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Sat, 3 Nov 2018 12:39:52 +0000 (12:39 +0000)
zpm-syncfs.c

index c08407e8c455efb0aa2d0be18da794323d64e7ff..99851880530b0ac0e130873010e9b951cb75f15a 100644 (file)
@@ -12,6 +12,7 @@
 #include <grp.h>
 #include <math.h>
 #include <stdarg.h>
+#include <time.h>
 
 /* needed for S_IFMT and AT_FDCWD */
 #include <fcntl.h>
@@ -32,6 +33,21 @@ struct config {
        int overwrite, absorb;
 };
 
+struct nitem {
+       int op;
+       char *opstr;
+       uid_t uid;
+       gid_t gid;
+       char *dest;
+       char *path;
+       char *hash;
+       char *target;
+       time_t mtime;
+       mode_t mode;
+       int ftype;
+       struct timespec times[2];
+};
+
 static void usage() {
        printf("usage: zpm $scriptname [-fncC] args ...\n");
 }
@@ -134,17 +150,18 @@ static int create_leading_dirs(char *path) {
 
                /* try to create the directory, if it exists
                 * and is a directory or a symlink, that's ok
+                * should be (eventually) a symlink to a directory
+                * so we want stat here, not lstat
                 */
                if (mkdir(pcopy, 0755) == -1) {
                        switch (errno) {
                                case EEXIST:
-                                       if (lstat(pcopy, &st) == -1) {
+                                       if (stat(pcopy, &st) == -1) {
                                                /* can't stat? */
                                                return 0;
                                        }
                                        switch (st.st_mode & S_IFMT) {
                                                case S_IFDIR:
-                                               case S_IFLNK:
                                                        break;
                                                default:
                                                        return 0;
@@ -239,6 +256,7 @@ static int check_existing(void *f, int ncols, char **vals, char **cols) {
 
        if (conf->dryrun) {
                printf("checkfor %s\n", path);
+               fflush(stdout);
                return 0;
        }
 
@@ -279,6 +297,7 @@ static int remove_files(void *f, int ncols, char **vals, char **cols) {
                        case 'd': printf("rmdir %s\n", dest); break;
                        default: printf("unlink %s\n", dest); break;
                }
+               fflush(stdout);
                return 0;
        }
 
@@ -310,20 +329,6 @@ static int remove_files(void *f, int ncols, char **vals, char **cols) {
 
 #define MARK fprintf(stderr, "%s %d: mark\n", __func__, __LINE__)
 
-struct nitem {
-       int op;
-       uid_t uid;
-       gid_t gid;
-       char *dest;
-       char *path;
-       char *hash;
-       char *target;
-       time_t mtime;
-       mode_t mode;
-       int ftype;
-       struct timespec times[2];
-};
-
 #define D_NOEXIST 0x1
 #define D_TYPE 0x2
 #define D_MD 0x4
@@ -417,6 +422,7 @@ static int read_item(struct config *conf, int ncols, char **vals, char **cols,
                seterror(conf, "can't determine op");
                return 0;
        }
+       n->opstr = val;
        n->op = getop(val);
        if (!n->op) {
                seterror(conf, "can't determine op");
@@ -512,7 +518,13 @@ static int read_item(struct config *conf, int ncols, char **vals, char **cols,
                n->gid = getegid();
        }
 
+       errno = 0;
        double mtime = strtod(COL("mtime"),NULL);
+       if (errno) {
+               mtime = (double)time(NULL);
+       }
+
+       n->mtime = (time_t)mtime;
 
        n->times[0].tv_sec = 0;
        n->times[0].tv_nsec = UTIME_OMIT;
@@ -546,15 +558,28 @@ static int remove_existing(struct config *conf, char *path) {
 
 static int set_md(struct config *conf, struct nitem *item) {
        int rv;
+       int success = 0;
+
+       if (conf->dryrun) {
+               printf("chmod %o %s\n", item->mode, item->dest);
+               if (conf->setuser && conf->setgroup) {
+                       printf("chown %d:%d %s\n", item->uid, item->gid,
+                                       item->dest);
+               }
+               printf("mtime %.0f %s\n", (double)item->mtime, item->dest);
+               fflush(stdout);
+               return success;
+       }
+
+       rv = chmod(item->dest, item->mode);
 
-       rv = chmod(item->path, item->mode);
        if (rv == -1) {
-               setsyserr(conf, "can't chmod");
+               setsyserr(conf, "can't chmod %o %s", item->mode, item->dest);
                return conf->errabort;
        }
 
        if (conf->setuser && conf->setgroup) {
-               rv = chown(item->path, item->uid, item->gid);
+               rv = chown(item->dest, item->uid, item->gid);
                if (rv == -1) {
                        setsyserr(conf, "can't chown %s", item->dest);
                        return conf->errabort;
@@ -563,7 +588,8 @@ static int set_md(struct config *conf, struct nitem *item) {
 
        rv = utimensat(AT_FDCWD, item->dest, item->times, AT_SYMLINK_NOFOLLOW);
        if (rv == -1) {
-               setsyserr(conf, "can't set mtime");
+               setsyserr(conf, "can't set mtime %.0f %s", (double)item->mtime,
+                               item->dest);
                return conf->errabort;
        }
        return 0;
@@ -591,6 +617,20 @@ static int install(struct config *conf, struct nitem *item, unsigned int flags)
                success = 1;
        }
 
+       if (conf->dryrun) {
+               if (unlink_file) {
+                       printf("unlink %s\n", item->dest);
+               } else if (rm_dir) {
+                       printf("rmdir %s\n", item->dest);
+               }
+
+               printf("install %c%o %d:%d %s -> %s\n", item->ftype,
+                               item->mode, item->uid, item->gid, item->path,
+                               item->dest);
+               fflush(stdout);
+               return success;
+       }
+
        source = conf->src ? conf->src : conf->log;
 
        if (unlink_file) {
@@ -656,25 +696,15 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
        }
 
        if (conf->verbose) {
-               fprintf(stderr, "%d '%c' %s\n", nitem.op, nitem.ftype,
+               fprintf(stderr, "%s '%c' %s\n", nitem.opstr, nitem.ftype,
                                nitem.dest);
        }
 
-       if (conf->dryrun) {
-               printf("new %c%o %d:%d %s -> %s\n", nitem.ftype, nitem.mode,
-                               nitem.uid, nitem.gid, nitem.path, nitem.dest);
-               return 0;
-       }
-
        unsigned int diffs = file_compare(&nitem, &existing);
        if (diffs >= D_ERROR) {
                return seterror(conf, "can't check %s", nitem.dest);
        }
 
-       if (conf->verbose) {
-               fprintf(stderr, "diffs = %u\n", diffs);
-       }
-
        /* updates:
         * exist & same type & md same & hash same: do nothing, but warn bug
         * exist & same type & md diff & hash same: fix md
@@ -773,11 +803,14 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                if (sametype) {
                        if (mdsame && hashsame && (accept || overwrite)) {
                                /* do nothing */
+                               if (conf->dryrun || conf->verbose) {
+                                       fprintf(stderr, "accepting existing file: %s\n", nitem.dest);
+                               }
                                return 0;
                        }
                        if (mdsame && hashsame && !(accept || overwrite)) {
                                /* error */
-                               return seterror(conf, "bad conditions");
+                               return seterror(conf, "will not accept or overwrite existing file: %s", nitem.dest);
                        }
                        if (mdsame && !hashsame && overwrite) {
                                /* install */
@@ -787,7 +820,7 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                                /* accept doesn't matter, since it's
                                 * not an acceptable file */
                                /* error */
-                               return seterror(conf, accept ? "existing file not acceptable" : "file exists");
+                               return seterror(conf, "%s (hashdiff): %s", accept ? "existing file not acceptable" : "file exists", nitem.dest);
                        }
                        if (!mdsame && hashsame && overwrite) {
                                /* fix md */
@@ -797,7 +830,7 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                                /* accept doesn't matter, since it's
                                 * not an acceptable file */
                                /* error */
-                               return seterror(conf, accept ? "existing file not acceptable" : "file exists");
+                               return seterror(conf, "%s (mddiff): %s", accept ? "existing file not acceptable" : "file exists", nitem.dest);
                        }
                        if (!mdsame && !hashsame && overwrite) {
                                /* install */
@@ -807,7 +840,7 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                                /* accept doesn't matter, since it's
                                 * not an acceptable file */
                                /* error */
-                               return seterror(conf, accept ? "existing file not acceptable" : "file exists");
+                               return seterror(conf, "%s (md+hash): %s", accept ? "existing file not acceptable" : "file exists", nitem.dest);
                        }
                        /* TODO error, should be impossible */
                        return seterror(conf, "impossible state reached");
@@ -816,7 +849,7 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                /* file exists, and is not the same type */
                if (!overwrite) {
                        /* error */
-                       return seterror(conf, accept ? "existing file not acceptable" : "file exists");
+                               return seterror(conf, "%s (difftype): %s", accept ? "existing file not acceptable" : "file exists", nitem.dest);
                }
 
                /* not the same type, but ok to overwrite */
@@ -843,6 +876,9 @@ static int install_files(void *f, int ncols, char **vals, char **cols) {
                return seterror(conf, "impossible state 2 reached");
        }
 
+       /* TODO extra verbose print perms, mtime, etc, probably ls -l
+        * format
+        */ 
        if (conf->verbose) {
                printf("%s\n", nitem.path);
        }
@@ -877,9 +913,6 @@ static void check_conflicts(struct config *conf, char *conflict_type,
        }
 
        sql = sqlite3_str_value(s);
-       if (conf->verbose > 2) {
-               fprintf(stderr, "stage query: %s\n", sql);
-       }
 
        rv = zpm_exec(conf->log, sql, callback, conf, &errmsg);
 
@@ -933,9 +966,6 @@ static void runstage(struct config *conf, char *stage,
        }
 
        sql = sqlite3_str_value(s);
-       if (conf->verbose > 2) {
-               fprintf(stderr, "stage query: %s\n", sql);
-       }
 
        rv = zpm_exec(conf->log, sql, callback, conf, &errmsg);
 
@@ -954,9 +984,11 @@ static void runstage(struct config *conf, char *stage,
                                conf->log->errmsg ? conf->log->errmsg : "unknown");
                conf->errors++;
        }
+#if 0
        if (conf->log->errmsg) {
                fprintf(stderr, "error: %s\n", conf->log->errmsg);
        }
+#endif
        if (conf->errors && conf->exitonerror) {
                zpm_close(conf->log);
                zpm_close(conf->src);
@@ -1063,6 +1095,7 @@ int main(int ac, char **av){
        conf.errors = 0;
        conf.exitonerror = 0;
        check_conflicts(&conf, NULL, report_conflicts);
+
        if (conf.conflicts) {
                fprintf(stderr, "%d conflicts reported, aborting sync\n",
                                conf.conflicts);
@@ -1071,32 +1104,34 @@ int main(int ac, char **av){
                /* no point in running it if we're just going to
                 * overwrite everything
                 */
-               if (conf.overwrite == 0 || conf.absorb == 0) {
+               if ((conf.overwrite == 0 || conf.absorb == 0) && !conf.dryrun) {
                        runstage(&conf, "new", check_existing);
                }
 
                if (conf.verbose) {
-                       fprintf(stderr, "beginning sync\n");
+                       fprintf(stderr, "beginning %ssync\n", conf.dryrun ?
+                                       "dryrun " : "");
                }
                /* have to do the removes first otherwise
                 * old files may conflict with update file
                 * type changes
                 */
                if (!conf.errors) {
-                       conf.exitonerror = 1;
+                       conf.exitonerror = conf.dryrun ? 0 : 1;
+                       conf.errabort = conf.dryrun ? 0 : 1;
                        conf.reverse = 1;
-               if (conf.verbose) {
-                       fprintf(stderr, "removing old files\n");
-               }
+                       if (conf.verbose) {
+                               fprintf(stderr, "removing old files\n");
+                       }
                        runstage(&conf, "remove", remove_files);
                        conf.reverse = 0;
-               if (conf.verbose) {
-                       fprintf(stderr, "updating files\n");
-               }
+                       if (conf.verbose) {
+                               fprintf(stderr, "updating files\n");
+                       }
                        runstage(&conf, "update", install_files);
-               if (conf.verbose) {
-                       fprintf(stderr, "installing files\n");
-               }
+                       if (conf.verbose) {
+                               fprintf(stderr, "installing files\n");
+                       }
                        runstage(&conf, "new", install_files);
                }
        }