]> pd.if.org Git - zpackage/blobdiff - lib/integ.c
add scripts to package hashing
[zpackage] / lib / integ.c
index 13a2505bf53b7bf5b1454392c0885a8c279777d7..c2f1e230f3f3721b0e8ee0b5c0b0d4f943ed1956 100644 (file)
@@ -1,19 +1,20 @@
 #define _POSIX_C_SOURCE 200809L
+#include <stdlib.h>
 #include <string.h>
 
 #include "zpm.h"
 #include "sqlite3.h"
-#include "sha256.h"
+#include "lib/blake2/ref/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;
 
@@ -56,7 +57,7 @@ static void hash_int(struct sha256_state *h, int i) {
  * 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 */
@@ -71,8 +72,8 @@ static void hash_query(struct zpm *zpm, const char *zSql, struct sha256_state *h
        int j;
        unsigned char x[9];
 
-       if (!zSql) return;
-       if (!zpm) return;
+       if (!zSql) return 0;
+       if (!zpm) return 0;
 
        db = zpm->db;
 
@@ -80,13 +81,13 @@ static void hash_query(struct zpm *zpm, const char *zSql, struct sha256_state *h
        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:
@@ -132,14 +133,14 @@ static void hash_query(struct zpm *zpm, const char *zSql, struct sha256_state *h
                                        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];
@@ -150,12 +151,15 @@ int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash) {
 
        /* find package */
 
-       sha256_init(&d);
+       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 */
 
@@ -163,40 +167,112 @@ int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash) {
                "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;
+       }
 
-       sha256_done(&d, tmp);
+       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;
 }