#define _POSIX_C_SOURCE 200809L
+#include <stdlib.h>
#include <string.h>
#include "zpm.h"
#include "sqlite3.h"
-#include "sha256.h"
+#include "blake2.h"
-static void hash_byte(struct sha256_state *h, int ch) {
+static void hash_byte(struct blake2b_state__ *h, int ch) {
unsigned char buf[1];
buf[0] = ch & 0xff;
- sha256_process(h, buf, 1);
+ blake2b_update(h, buf, 1);
}
/* i will be positive, we are hashing column sizes */
-static void hash_int(struct sha256_state *h, int i) {
+static void hash_int(struct blake2b_state__ *h, int i) {
int n;
uint64_t z;
* with no delimiters of any kind.
*/
-static void hash_query(struct zpm *zpm, const char *zSql, struct sha256_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);
while (sqlite3_step(pStmt) == SQLITE_ROW) {
- sha256_process(h, (const unsigned char *)"R", 1);
+ blake2b_update(h, "R", 1);
for (i = 0; i < nCol; i++) {
switch (sqlite3_column_type(pStmt, i)) {
case SQLITE_NULL:
continue;
break;
}
- sha256_process(h, data, bytes);
+ blake2b_update(h, data, bytes);
}
}
- sqlite3_finalize(pStmt);
+ return sqlite3_finalize(pStmt);
}
int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash) {
- struct sha256_state d;
+ struct blake2b_state__ d;
char *sql;
int i;
unsigned char tmp[32];
return 0;
}
- sha256_init(&d);
/* find package */
+ blake2b_init(&d, 32);
+
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;
+ }
- sha256_done(&d, tmp);
+ /* package dependencies */
+ 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 stage,hash",
+ pkgid);
+ 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;
+
+ if (!zpm || !zpm->db || !pkgid) {
+ return 0;
+ }
- return 1;
+ 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;
}