예제 #1
0
파일: update.c 프로젝트: AsherBond/pkg
/**
 * 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);
}
예제 #2
0
파일: init.c 프로젝트: dpl0/pkg
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);
}
예제 #3
0
파일: pkgdb_repo.c 프로젝트: ppentchev/pkg
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);
}
예제 #4
0
파일: update.c 프로젝트: renchap/pkg
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
			}
		};
예제 #5
0
파일: init.c 프로젝트: dpl0/pkg
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);
}
예제 #6
0
파일: init.c 프로젝트: dpl0/pkg
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);
}