/** * Fetch repository calalogues. */ int pkgcli_update(bool force, bool strict, const char *reponame) { int retcode = EPKG_FATAL, update_count = 0, total_count = 0; struct pkg_repo *r = NULL; /* Only auto update if the user has write access. */ if (pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE, PKGDB_DB_REPO) == EPKG_ENOACCESS) return (EPKG_OK); if (pkg_repos_total_count() == 0) { fprintf(stderr, "No valid repository found.\n"); return (EPKG_FATAL); } while (pkg_repos(&r) == EPKG_OK) { if (reponame != NULL) { if (strcmp(pkg_repo_name(r), reponame) != 0) continue; } else { if (!pkg_repo_enabled(r)) continue; } if (!quiet) printf("Updating %s repository catalogue...\n", pkg_repo_name(r)); retcode = pkg_update(r, force); if (retcode == EPKG_UPTODATE) { if (!quiet) printf("%s repository is up-to-date.\n", pkg_repo_name(r)); } else if (retcode != EPKG_OK && strict) retcode = EPKG_FATAL; total_count ++; if (retcode != EPKG_OK) continue; update_count ++; } if (!strict || retcode == EPKG_UPTODATE) retcode = EPKG_OK; if (total_count == 0) { if (!quiet) printf("No repositories are enabled.\n"); retcode = EPKG_FATAL; } else if (update_count == 0) { if (!quiet) if (retcode == EPKG_OK) printf("All repositories are up-to-date.\n"); } return (retcode); }
int pkg_repo_binary_access(struct pkg_repo *repo, unsigned mode) { const pkg_object *o; const char *dbdir; int ret = EPKG_OK; o = pkg_config_get("PKG_DBDIR"); dbdir = pkg_object_string(o); ret = pkgdb_check_access(mode, dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo))); return (ret); }
const char * pkgdb_get_reponame(struct pkgdb *db, const char *repo) { const char *reponame = NULL; struct pkg_repo *r; assert(db->type == PKGDB_REMOTE); if (repo != NULL) { if ((r = pkg_repo_find_ident(repo)) == NULL) { pkg_emit_error("repository '%s' does not exist", repo); return (NULL); } reponame = pkg_repo_name(r); if (!pkgdb_is_attached(db->sqlite, reponame)) { pkg_emit_error("repository '%s' does not exist", repo); return (NULL); } } return (reponame); }
int pkg_update(struct pkg_repo *repo, bool force) { char repofile[MAXPATHLEN]; const char *dbdir = NULL; struct stat st; time_t t = 0; sqlite3 *sqlite = NULL; char *req = NULL; int64_t res; sqlite3_initialize(); if (pkg_config_string(PKG_CONFIG_DBDIR, &dbdir) != EPKG_OK) { pkg_emit_error("Cant get dbdir config entry"); return (EPKG_FATAL); } snprintf(repofile, sizeof(repofile), "%s/%s.sqlite", dbdir, pkg_repo_name(repo)); if (stat(repofile, &st) != -1) t = force ? 0 : st.st_mtime; if (t != 0) { if (sqlite3_open(repofile, &sqlite) != SQLITE_OK) { pkg_emit_error("Unable to open local database"); return (EPKG_FATAL); } if (get_pragma(sqlite, "SELECT count(name) FROM sqlite_master " "WHERE type='table' AND name='repodata';", &res) != EPKG_OK) { pkg_emit_error("Unable to query repository"); sqlite3_close(sqlite); return (EPKG_FATAL); } if (res != 1) { t = 0; if (sqlite != NULL) { sqlite3_close(sqlite); sqlite = NULL; } } } if (t != 0) { req = sqlite3_mprintf("select count(key) from repodata " "WHERE key = \"packagesite\" and value = '%q'", pkg_repo_url(repo)); if (get_pragma(sqlite, req, &res) != EPKG_OK) { sqlite3_free(req); pkg_emit_error("Unable to query repository"); sqlite3_close(sqlite); return (EPKG_FATAL); } sqlite3_free(req); if (res != 1) { t = 0; if (sqlite != NULL) { sqlite3_close(sqlite); sqlite = NULL; } unlink(repofile); } } res = pkg_update_incremental(repofile, repo, &t); if (res != EPKG_OK && res != EPKG_UPTODATE) { pkg_emit_notice("No digest falling back on legacy catalog format"); /* Still try to do full upgrade */ if ((res = pkg_update_full(repofile, repo, &t)) != EPKG_OK) goto cleanup; } res = EPKG_OK; cleanup: /* Set mtime from http request if possible */ if (t != 0) { struct timeval ftimes[2] = { { .tv_sec = t, .tv_usec = 0 }, { .tv_sec = t, .tv_usec = 0 } };
int pkg_repo_binary_create(struct pkg_repo *repo) { char filepath[MAXPATHLEN]; struct statfs stfs; const char *dbdir = NULL; sqlite3 *sqlite = NULL; int retcode; sqlite3_initialize(); dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR")); snprintf(filepath, sizeof(filepath), "%s/%s", dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo))); /* Should never ever happen */ if (access(filepath, R_OK) == 0) return (EPKG_CONFLICT); /* * Fall back on unix-dotfile locking strategy if on a network filesystem */ if (statfs(dbdir, &stfs) == 0) { if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL) sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1); } /* Open for read/write/create */ if (sqlite3_open(filepath, &sqlite) != SQLITE_OK) return (EPKG_FATAL); retcode = sql_exec(sqlite, binary_repo_initsql, REPO_SCHEMA_VERSION); if (retcode == EPKG_OK) { sqlite3_stmt *stmt; const char sql[] = "" "INSERT OR REPLACE INTO repodata (key, value) " "VALUES (\"packagesite\", ?1);"; /* register the packagesite */ if (sql_exec(sqlite, "CREATE TABLE IF NOT EXISTS repodata (" " key TEXT UNIQUE NOT NULL," " value TEXT NOT NULL" ");") != EPKG_OK) { pkg_emit_error("Unable to register the packagesite in the " "database"); retcode = EPKG_FATAL; goto cleanup; } if (sqlite3_prepare_v2(sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(sqlite, sql); retcode = EPKG_FATAL; goto cleanup; } sqlite3_bind_text(stmt, 1, pkg_repo_url(repo), -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) { ERROR_SQLITE(sqlite, sql); sqlite3_finalize(stmt); retcode = EPKG_FATAL; goto cleanup; } sqlite3_finalize(stmt); } cleanup: sqlite3_close(sqlite); return (retcode); }
int pkg_repo_binary_open(struct pkg_repo *repo, unsigned mode) { char filepath[MAXPATHLEN]; struct statfs stfs; const char *dbdir = NULL; sqlite3 *sqlite = NULL; int flags; int64_t res; struct pkg_repo_it *it; struct pkg *pkg = NULL; const char *digest; sqlite3_initialize(); dbdir = pkg_object_string(pkg_config_get("PKG_DBDIR")); /* * Fall back on unix-dotfile locking strategy if on a network filesystem */ if (statfs(dbdir, &stfs) == 0) { if ((stfs.f_flags & MNT_LOCAL) != MNT_LOCAL) sqlite3_vfs_register(sqlite3_vfs_find("unix-dotfile"), 1); } snprintf(filepath, sizeof(filepath), "%s/%s.meta", dbdir, pkg_repo_name(repo)); /* Open metafile */ if (access(filepath, R_OK) != -1) { if (pkg_repo_meta_load(filepath, &repo->meta) != EPKG_OK) return (EPKG_FATAL); } snprintf(filepath, sizeof(filepath), "%s/%s", dbdir, pkg_repo_binary_get_filename(pkg_repo_name(repo))); /* Always want read mode here */ if (access(filepath, R_OK | mode) != 0) return (EPKG_ENOACCESS); flags = (mode & W_OK) != 0 ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; if (sqlite3_open_v2(filepath, &sqlite, flags, NULL) != SQLITE_OK) return (EPKG_FATAL); /* Sanitise sqlite database */ if (get_pragma(sqlite, "SELECT count(name) FROM sqlite_master " "WHERE type='table' AND name='repodata';", &res, false) != EPKG_OK) { pkg_emit_error("Unable to query repository"); sqlite3_close(sqlite); return (EPKG_FATAL); } if (res != 1) { pkg_emit_notice("Repository %s contains no repodata table, " "need to re-create database", repo->name); sqlite3_close(sqlite); return (EPKG_FATAL); } /* Check package site */ char *req = sqlite3_mprintf("select count(key) from repodata " "WHERE key = \"packagesite\" and value = '%q'", pkg_repo_url(repo)); res = 0; get_pragma(sqlite, req, &res, true); sqlite3_free(req); if (res != 1) { pkg_emit_notice("Repository %s has a wrong packagesite, need to " "re-create database", repo->name); sqlite3_close(sqlite); return (EPKG_FATAL); } /* Check version */ if (pkg_repo_binary_check_version(repo, sqlite) != EPKG_OK) { pkg_emit_error("need to re-create repo %s to upgrade schema version", repo->name); sqlite3_close(sqlite); if (mode & W_OK) unlink(filepath); return (EPKG_REPOSCHEMA); } repo->priv = sqlite; /* Check digests format */ if ((it = pkg_repo_binary_query(repo, NULL, MATCH_ALL)) == NULL) return (EPKG_OK); if (it->ops->next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) { it->ops->free(it); return (EPKG_OK); } it->ops->free(it); pkg_get(pkg, PKG_DIGEST, &digest); if (digest == NULL || !pkg_checksum_is_valid(digest, strlen(digest))) { pkg_emit_notice("Repository %s has incompatible checksum format, need to " "re-create database", repo->name); pkg_free(pkg); sqlite3_close(sqlite); repo->priv = NULL; return (EPKG_FATAL); } pkg_free(pkg); return (EPKG_OK); }