struct zpm *src;
char *dbfile;
char *rootdir;
- int errabort, errors, verbose, dryrun;
+ int errabort, errors, verbose, dryrun, conflicts;
int setuser, setgroup;
int reverse, exitonerror;
};
static int report_conflicts(void *f, int ncols, char **vals, char **cols) {
struct config *conf = f;
- char *path;
- char *pkg;
+ char *path, *hash, *pkg, *conflict_type, *mds;
pkg = COL("pkgid");
path = COL("path");
+ conflict_type = COL("conflict");
+ if (!strcmp(conflict_type, "hash")) {
+ hash = COL("hash");
+ fprintf(stderr, "hash conflict: package %s path %s hash %.8s\n",
+ pkg, path, hash);
+ } else
+ if (!strcmp(conflict_type, "md")) {
+ mds = COL("mds");
+ fprintf(stderr, "md conflict: package %s path %s md %s\n",
+ pkg, path, mds);
+ } else {
+ fprintf(stderr, "%s conflict: package %s path %s\n",
+ conflict_type, pkg, path);
+ }
- conf->errors++;
- fprintf(stderr, "%s owned by %s\n", path, pkg);
+ conf->conflicts++;
return 0;
}
return 0;
}
+#define MARK fprintf(stderr, "%s %d: mark\n", __func__, __LINE__)
+
static int install_files(void *f, int ncols, char **vals, char **cols) {
struct config *conf = f;
struct passwd *pw;
return 0;
}
+static void check_conflicts(struct config *conf, char *conflict_type,
+ int (callback)(void *, int, char **, char **)) {
+ int rv;
+ char *errmsg;
+ sqlite3_str *s;
+ char *sql;
+
+ s = sqlite3_str_new(conf->log->db);
+ sqlite3_str_appendall(s, "select *, ");
+ if (conf->rootdir) {
+ sqlite3_str_appendf(s, "printf('%%s/%%s',rtrim(%Q,'/'),ltrim(path,'/'))", conf->rootdir);
+ } else {
+ sqlite3_str_appendf(s, "printf('/%%s', trim(path, '/'))");
+ }
+ sqlite3_str_appendall(s, " as dest from syncconflicts");
+
+ if (conflict_type) {
+ sqlite3_str_appendf(s," where conflict = %Q", conflict_type);
+ }
+ if (conf->reverse) {
+ sqlite3_str_appendall(s," order by length(path) desc, path desc,pkgid collate vercmp desc, conflict desc");
+ } else {
+ sqlite3_str_appendall(s," order by length(path), path, pkgid collate vercmp, conflict");
+
+ }
+
+ 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);
+
+ sqlite3_str_finish(s);
+
+ if (rv) {
+ fprintf(stderr, "exec fail: %s\n", sqlite3_errstr(rv));
+ if (errmsg) {
+ fprintf(stderr, "database error: %s\n", errmsg);
+ conf->errors++;
+ }
+ if (conf->log->error == 1) {
+ fprintf(stderr, "unable to allocate memory\n");
+ }
+ fprintf(stderr, "zpm_exec failure: %s\n",
+ conf->log->errmsg ? conf->log->errmsg : "unknown");
+ conf->errors++;
+ }
+ if (conf->log->errmsg) {
+ fprintf(stderr, "error: %s\n", conf->log->errmsg);
+ }
+ if (conf->errors && conf->exitonerror) {
+ zpm_close(conf->log);
+ zpm_close(conf->src);
+ exit(EXIT_FAILURE);
+ }
+ /* TODO final report function in conf var */
+}
+
static void runstage(struct config *conf, char *stage,
int (callback)(void *, int, char **, char **)) {
int rv;
} else {
sqlite3_str_appendf(s, "printf('/%%s', trim(path, '/'))");
}
- sqlite3_str_appendall(s, " as dest from install_status");
+ sqlite3_str_appendall(s, " as dest from syncinfo");
if (stage) {
sqlite3_str_appendf(s," where op = %Q", stage);
conf.errabort = 1;
conf.errors = 0;
+ conf.conflicts = 0;
conf.verbose = 0;
conf.dryrun = 0;
conf.setuser = 1;
conf.errors = 0;
conf.exitonerror = 0;
- runstage(&conf, "conflict", report_conflicts);
- runstage(&conf, "new", check_existing);
-
- if (!conf.errors) {
- conf.exitonerror = 1;
- runstage(&conf, "new", install_files);
- runstage(&conf, "update", update_files);
- conf.reverse = 1;
- runstage(&conf, "remove", remove_files);
- conf.reverse = 0;
+ check_conflicts(&conf, NULL, report_conflicts);
+ if (conf.conflicts) {
+ fprintf(stderr, "%d conflicts reported, aborting sync\n",
+ conf.conflicts);
+ conf.errors++;
+ } else {
+ runstage(&conf, "new", check_existing);
+
+ if (!conf.errors) {
+ conf.exitonerror = 1;
+ runstage(&conf, "new", install_files);
+ runstage(&conf, "update", update_files);
+ conf.reverse = 1;
+ runstage(&conf, "remove", remove_files);
+ conf.reverse = 0;
+ }
}
zpm_close(&localdb);