+int zpm_foreach_script(struct zpm *zpm, char *pkgstr, char *stage, void *cbd,
+ int (*cb)(void *ud, const char *pkg, const char *stage, const char *hash)) {
+ char *pkgid = 0;
+ char *sql;
+ sqlite3_str *s;
+ sqlite3_stmt *st;
+
+ char *find = "select printf('%%s-%%s-%%d', package, version, release) as pkgid, stage, hash from scripts where true";
+ char *pkgidwhere = " and printf('%%%%s-%%%%s-%%%%d', package, version, release) = %Q";
+ char *stagewhere = " and stage = %Q";
+
+ if (!zpm || !cb) {
+ return 0;
+ }
+ if (zpm->error) {
+ return 0;
+ }
+
+ if (pkgstr) {
+ pkgid = zpm_findpkg(zpm, pkgstr, 0);
+ if (!pkgid) {
+ return 0;
+ }
+ }
+
+ s = sqlite3_str_new(zpm->db);
+ sqlite3_str_appendall(s, find);
+
+ if (pkgid) {
+ sqlite3_str_appendf(s, pkgidwhere, pkgid);
+ }
+
+ if (stage) {
+ sqlite3_str_appendf(s, stagewhere, stage);
+ }
+
+ sql = sqlite3_str_finish(s);
+ if (!sql) {
+ zpm->error = 1;
+ if (pkgid) {
+ free(pkgid);
+ }
+ return 0;
+ }
+
+ st = zpm_dbquery(zpm, sql);
+
+ if (!st) {
+ zpm->error = 1;
+ sqlite3_free(sql);
+ return 0;
+ }
+
+ int rv, cbrv = 0;
+ while ((rv = sqlite3_step(st)) == SQLITE_ROW) {
+ if (cb) {
+ const char *sstage, *spkgid, *shash;
+ int cbrv;
+
+ spkgid = (const char *)sqlite3_column_text(st, 0);
+ sstage = (const char *)sqlite3_column_text(st, 1);
+ shash = (const char *)sqlite3_column_text(st, 2);
+
+ cbrv = cb(cbd, spkgid, sstage, shash);
+ if (cbrv) {
+ break;
+ }
+ }
+ }
+
+ if (rv != SQLITE_DONE) {
+ zpm->dbresult = rv;
+ zpm->error = 1;
+ }
+
+ if (pkgid) {
+ free(pkgid);
+ }
+
+ sqlite3_free(sql);
+ return cbrv;
+}
+