#define _POSIX_C_SOURCE 200809L
+#include <stdlib.h>
#include <string.h>
#include "zpm.h"
* with no delimiters of any kind.
*/
-static void hash_query(struct zpm *zpm, const char *zSql, struct blake2b_state__ *h) {
+static int hash_query(struct zpm *zpm, const char *zSql, struct blake2b_state__ *h) {
sqlite3 *db;
sqlite3_stmt *pStmt = 0;
int nCol; /* Number of columns in the result set */
int j;
unsigned char x[9];
- if (!zSql) return;
- if (!zpm) return;
+ if (!zSql) return 0;
+ if (!zpm) return 0;
db = zpm->db;
if (rc) {
zpm->dberrmsg = strdup(sqlite3_errmsg(db));
sqlite3_finalize(pStmt);
- return;
+ return rc;
}
nCol = sqlite3_column_count(pStmt);
blake2b_update(h, data, bytes);
}
}
- sqlite3_finalize(pStmt);
+ return sqlite3_finalize(pStmt);
}
int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash) {
sql = sqlite3_mprintf("select package,version,release,description,architecture,url,licenses,packager,build_time from packages_pkgid where pkgid = %Q", pkgid);
- hash_query(zpm, sql, &d);
+ i = hash_query(zpm, sql, &d);
sqlite3_free(sql);
+ if (i) {
+ return i;
+ }
/* hash package files */
"filetype, target, device, mtime, hash "
"from packagefiles_pkgid where pkgid = %Q order by path",
pkgid);
- hash_query(zpm, sql, &d);
+ i = hash_query(zpm, sql, &d);
sqlite3_free(sql);
+ if (i) {
+ return i;
+ }
/* package dependencies */
- sql = sqlite3_mprintf("dselect requires from packagedeps"
+ sql = sqlite3_mprintf("select requires from packagedeps"
+ " where printf('%%q-%%q-%%d',package,version,release) = %Q"
+ " order by requires",
+ pkgid);
+ i = hash_query(zpm, sql, &d);
+ sqlite3_free(sql);
+ if (i) {
+ return i;
+ }
+
+ /* package scripts */
+ sql = sqlite3_mprintf("select stage,hash from scripts"
" where printf('%%q-%%q-%%d',package,version,release) = %Q"
- "order by requires",
+ " order by stage,hash",
pkgid);
- hash_query(zpm, sql, &d);
+ i = hash_query(zpm, sql, &d);
sqlite3_free(sql);
+ if (i) {
+ return i;
+ }
blake2b_final(&d, tmp, sizeof tmp);
for (i=0; i<32; i++) {
sprintf(hash+i*2, "%02x", (unsigned)tmp[i]);
}
- hash[64] = 0;
- return 1;
+ return 0;
}
int zpm_package_sethash(struct zpm *zpm, char *pkgid, char *hash) {
char buf[ZPM_HASH_STRLEN + 1];
- char *sql;
if (!hash) {
hash = buf;
}
zpm_package_hash(zpm, pkgid, hash);
+ hash[ZPM_HASH_STRLEN] = 0;
- sql = sqlite3_mprintf("update packages_pkgid set hash = %Q where pkgid = %Q", hash, pkgid);
+ return zpm_db_run(zpm, "update packages_pkgid set hash = %Q where pkgid = %Q", hash, pkgid);
+}
- zpm_exec(zpm, sql, NULL, NULL, NULL);
- sqlite3_free(sql);
+int zpm_package_clearhash(struct zpm *zpm, char *pkgid) {
+ if (!zpm || !zpm->db) {
+ return 1;
+ }
+
+ return zpm_db_run(zpm, "update packages_pkgid set hash = NULL where pkgid = %Q", pkgid);
+}
+
+char *zpm_package_gethash(struct zpm *zpm, char *pkgid, char *hash) {
+ char *saved;
- return 1;
+ if (!zpm || !zpm->db || !pkgid) {
+ return 0;
+ }
+
+ saved = zpm_db_string(zpm, "select hash from packages_pkgid where pkgid = %Q", pkgid);
+ if (saved && hash) {
+ strncpy(hash, saved, ZPM_HASH_STRLEN);
+ free(saved);
+ return hash;
+ }
+ return saved;
+}
+
+/* calc vs stored (hash == 0)
+ *
+ * otherwise check both.
+ * 0 == match both
+ * 1 = no match stored
+ * 2 = no match calc
+ * 3 = no match either
+ * 4 = no such pkgid
+ */
+int zpm_package_checkhash(struct zpm *zpm, char *pkgid, char *hash) {
+ /* check calculated hash against stored hash */
+ char calc[ZPM_HASH_STRLEN];
+ char set[ZPM_HASH_STRLEN];
+ char *current;
+ int rv = 0;
+
+ zpm_package_hash(zpm, pkgid, calc);
+ current = zpm_package_gethash(zpm, pkgid, set);
+ if (!current) {
+ rv |= 1;
+ }
+
+ if (hash) {
+ if (current && memcmp(hash, current, ZPM_HASH_STRLEN)) {
+ rv |= 1;
+ }
+ if (memcmp(hash, calc, ZPM_HASH_STRLEN)) {
+ rv |= 2;
+ }
+ } else {
+ if (current) {
+ rv = memcmp(calc, current, ZPM_HASH_STRLEN) ? 1 : 0;
+ }
+ }
+ return rv;
}
int opt, argn;
struct zpm pkg;
char *dbfile;
+ int fail = 0;
int set = 0, clear = 0, showcurrent = 0;
int check = 0, quiet = 0, checkfail = 0, verbose = 0;
- char hash[ZPM_HASH_STRLEN+1];
+ char hash[ZPM_HASH_STRLEN+1] = { 0 };
char *pkgid = 0, *current = 0, *display = hash;
dbfile = getenv("ZPMDB");
exit(EXIT_FAILURE);
}
if (check || showcurrent) {
- current = zpm_db_string(&pkg, "select hash from packages_pkgid where pkgid = %Q", pkgid);
+ current = zpm_package_gethash(&pkg, pkgid, 0);
}
if (check) {
- checkfail = 1;
- if (current) {
- zpm_package_hash(&pkg, pkgid, hash);
- checkfail = strcmp(current, hash);
- }
+ fail = zpm_package_checkhash(&pkg, pkgid, 0);
} else if (set) {
- zpm_package_sethash(&pkg, pkgid, hash);
+ fail = zpm_package_sethash(&pkg, pkgid, hash);
} else if (clear) {
- zpm_package_sethash(&pkg, pkgid, NULL);
- display = NULL;
+ fail = zpm_package_clearhash(&pkg, pkgid);
} else if (showcurrent) {
display = current;
} else {
- zpm_package_hash(&pkg, pkgid, hash);
+ fail = zpm_package_hash(&pkg, pkgid, hash);
}
zpm_close(&pkg);
- if (display && !quiet) {
+ if (display && !quiet && !fail) {
if (verbose) {
printf("%s ", pkgid);
}
int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash);
int zpm_package_sethash(struct zpm *zpm, char *pkgid, char *hash);
+int zpm_package_checkhash(struct zpm *zpm, char *pkgid, char *hash);
+char *zpm_package_gethash(struct zpm *zpm, char *pkgid, char *hash);
+int zpm_package_clearhash(struct zpm *zpm, char *pkgid);
sqlite3_stmt *zpm_dbqueryv(struct zpm *zpm, char *query, va_list args);
sqlite3_stmt *zpm_dbquery(struct zpm *zpm, char *query, ...);
char *zpm_db_string(struct zpm *zpm, char *query, ...);
int zpm_db_int(struct zpm *zpm, char *query, ...);
-void zpm_db_run(struct zpm *zpm, char *query, ...);
+int zpm_db_run(struct zpm *zpm, char *query, ...);
void zpm_seterror(struct zpm *zpm, char *msgfmt, ...);
struct zpm *zpm_clearmem(struct zpm *zpm);