1 #define _POSIX_C_SOURCE 200809L
9 static void hash_byte(struct blake2b_state__ *h, int ch) {
13 blake2b_update(h, buf, 1);
16 /* i will be positive, we are hashing column sizes */
17 static void hash_int(struct blake2b_state__ *h, int i) {
25 hash_byte(h, (int)(z & 0xff));
31 * Implementation of the sha3_query(SQL,SIZE) function.
33 * This function compiles and runs the SQL statement(s) given in the argument.
34 * The results are hashed using a SIZE-bit SHA3. The default size is 256.
36 * The format of the byte stream that is hashed is summarized as follows:
45 * <sql> is the original SQL text for each statement run and <n> is the size of
46 * that text. The SQL text is UTF-8. A single R character occurs before the
47 * start of each row. N means a NULL value. I mean an 8-byte little-endian
48 * integer <int>. F is a floating point number with an 8-byte little-endian
49 * IEEE floating point value <ieee-float>. B means blobs of <size> bytes. T
50 * means text rendered as <size> bytes of UTF-8. The <size> values are
51 * expressed as little endian 8 byte integers.
54 * There are zero or more R segments, one for each row in the
55 * result set. After each R, there are one or more N, I, F, B, or T segments,
56 * one for each column in the result set. Segments are concatentated directly
57 * with no delimiters of any kind.
60 static int hash_query(struct zpm *zpm, const char *zSql, struct blake2b_state__ *h) {
62 sqlite3_stmt *pStmt = 0;
63 int nCol; /* Number of columns in the result set */
66 const unsigned char *data;
80 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
82 zpm->dberrmsg = strdup(sqlite3_errmsg(db));
83 sqlite3_finalize(pStmt);
87 nCol = sqlite3_column_count(pStmt);
89 while (sqlite3_step(pStmt) == SQLITE_ROW) {
90 blake2b_update(h, "R", 1);
91 for (i = 0; i < nCol; i++) {
92 switch (sqlite3_column_type(pStmt, i)) {
98 v = sqlite3_column_int64(pStmt, i);
100 for (j = 8; j >= 1; j--) {
109 r = sqlite3_column_double(pStmt, i);
111 for (j = 8; j >= 1; j--) {
120 bytes = sqlite3_column_bytes(pStmt, i);
121 data = sqlite3_column_text(pStmt, i);
126 bytes = sqlite3_column_bytes(pStmt, i);
127 data = sqlite3_column_blob(pStmt, i);
136 blake2b_update(h, data, bytes);
139 return sqlite3_finalize(pStmt);
142 int zpm_package_hash(struct zpm *zpm, char *pkgid, char *hash) {
143 struct blake2b_state__ d;
146 unsigned char tmp[32];
154 blake2b_init(&d, 32);
156 sql = sqlite3_mprintf("select package,version,release,description,architecture,url,licenses,packager,build_time from packages_pkgid where pkgid = %Q", pkgid);
158 i = hash_query(zpm, sql, &d);
164 /* hash package files */
166 sql = sqlite3_mprintf("select path, mode, username, groupname, configuration, "
167 "filetype, target, device, mtime, hash "
168 "from packagefiles_pkgid where pkgid = %Q order by path",
170 i = hash_query(zpm, sql, &d);
176 /* package dependencies */
177 sql = sqlite3_mprintf("select requires from packagedeps"
178 " where printf('%%q-%%q-%%d',package,version,release) = %Q"
179 " order by requires",
181 i = hash_query(zpm, sql, &d);
187 /* package scripts */
188 sql = sqlite3_mprintf("select stage,hash from scripts"
189 " where printf('%%q-%%q-%%d',package,version,release) = %Q"
190 " order by stage,hash",
192 i = hash_query(zpm, sql, &d);
198 blake2b_final(&d, tmp, sizeof tmp);
199 for (i=0; i<32; i++) {
200 sprintf(hash+i*2, "%02x", (unsigned)tmp[i]);
206 int zpm_package_sethash(struct zpm *zpm, char *pkgid, char *hash) {
207 char buf[ZPM_HASH_STRLEN + 1];
213 zpm_package_hash(zpm, pkgid, hash);
214 hash[ZPM_HASH_STRLEN] = 0;
216 return zpm_db_run(zpm, "update packages_pkgid set hash = %Q where pkgid = %Q", hash, pkgid);
219 int zpm_package_clearhash(struct zpm *zpm, char *pkgid) {
220 if (!zpm || !zpm->db) {
224 return zpm_db_run(zpm, "update packages_pkgid set hash = NULL where pkgid = %Q", pkgid);
227 char *zpm_package_gethash(struct zpm *zpm, char *pkgid, char *hash) {
230 if (!zpm || !zpm->db || !pkgid) {
234 saved = zpm_db_string(zpm, "select hash from packages_pkgid where pkgid = %Q", pkgid);
236 strncpy(hash, saved, ZPM_HASH_STRLEN);
243 /* calc vs stored (hash == 0)
245 * otherwise check both.
247 * 1 = no match stored
249 * 3 = no match either
252 int zpm_package_checkhash(struct zpm *zpm, char *pkgid, char *hash) {
253 /* check calculated hash against stored hash */
254 char calc[ZPM_HASH_STRLEN];
255 char set[ZPM_HASH_STRLEN];
259 zpm_package_hash(zpm, pkgid, calc);
260 current = zpm_package_gethash(zpm, pkgid, set);
266 if (current && memcmp(hash, current, ZPM_HASH_STRLEN)) {
269 if (memcmp(hash, calc, ZPM_HASH_STRLEN)) {
274 rv = memcmp(calc, current, ZPM_HASH_STRLEN) ? 1 : 0;