Exemplo n.º 1
0
int
repodata_flush(struct xbps_handle *xhp, const char *repodir,
	xbps_dictionary_t idx, xbps_dictionary_t idxfiles)
{
	struct archive *ar;
	mode_t myumask;
	char *repofile, *tname, *xml;
	int repofd;

	/* Create a tempfile for our repository archive */
	repofile = xbps_repo_path(xhp, repodir);
	tname = xbps_xasprintf("%s.XXXXXXXXXX", repofile);
	if ((repofd = mkstemp(tname)) == -1)
		return errno;

	/* Create and write our repository archive */
	ar = archive_write_new();
	assert(ar);
	archive_write_set_compression_gzip(ar);
	archive_write_set_format_pax_restricted(ar);
	archive_write_set_options(ar, "compression-level=9");
	archive_write_open_fd(ar, repofd);

	xml = xbps_dictionary_externalize(idx);
	assert(xml);
	if (xbps_archive_append_buf(ar, xml, strlen(xml),
	    XBPS_PKGINDEX, 0644, "root", "root") != 0) {
		free(xml);
		return -1;
	}
	free(xml);

	xml = xbps_dictionary_externalize(idxfiles);
	assert(xml);
	if (xbps_archive_append_buf(ar, xml, strlen(xml),
	    XBPS_PKGINDEX_FILES, 0644, "root", "root") != 0) {
		free(xml);
		return -1;
	}
	free(xml);

	archive_write_finish(ar);

	/* Write data to tempfile and rename */
	fdatasync(repofd);
	myumask = umask(0);
	(void)umask(myumask);
	assert(fchmod(repofd, 0666 & ~myumask) != -1);
	close(repofd);
	rename(tname, repofile);
	free(repofile);
	free(tname);

	return 0;
}
Exemplo n.º 2
0
static bool
repo_open_remote(struct xbps_repo *repo)
{
	char *rpath;
	bool rv;

	rpath = xbps_repo_path(repo->xhp, repo->uri);
	rv = xbps_repo_fetch_remote(repo, rpath);
	free(rpath);
	if (rv) {
		xbps_dbg_printf(repo->xhp, "[repo] `%s' used remotely (kept in memory).\n", repo->uri);
		if (repo->xhp->state_cb && xbps_repo_key_import(repo) != 0)
			rv = false;
	}
	return rv;
}
Exemplo n.º 3
0
bool
xbps_repo_lock(struct xbps_handle *xhp, const char *repodir,
		int *lockfd, char **lockfname)
{
	char *repofile, *lockfile;
	int fd, rv;

	assert(repodir);
	assert(lockfd);
	assert(lockfname);

	repofile = xbps_repo_path(xhp, repodir);
	assert(repofile);

	lockfile = xbps_xasprintf("%s.lock", repofile);
	free(repofile);

	for (;;) {
		fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0660);
		rv = errno;
		if (fd != -1)
			break;
		if (rv != EEXIST) {
			xbps_dbg_printf(xhp, "[repo] `%s' failed to "
			    "create lock file %s\n", lockfile, strerror(rv));
			free(lockfile);
			return false;
		} else {
			xbps_dbg_printf(xhp, "[repo] `%s' lock file exists,"
			    "waiting for 1s...\n", lockfile);
			sleep(1);
		}
	}
	*lockfname = lockfile;
	*lockfd = fd;
	return true;
}
Exemplo n.º 4
0
struct xbps_repo *
xbps_repo_open(struct xbps_handle *xhp, const char *url)
{
	struct xbps_repo *repo;
	const char *arch;
	char *repofile;

	assert(xhp);
	assert(url);

	if (xhp->target_arch)
		arch = xhp->target_arch;
	else
		arch = xhp->native_arch;

	repo = calloc(1, sizeof(struct xbps_repo));
	assert(repo);
	repo->fd = -1;
	repo->xhp = xhp;
	repo->uri = url;

	if (xbps_repository_is_remote(url)) {
		/* remote repository */
		char *rpath;

		if ((rpath = xbps_get_remote_repo_string(url)) == NULL) {
			free(repo);
			return NULL;
		}
		repofile = xbps_xasprintf("%s/%s/%s-repodata", xhp->metadir, rpath, arch);
		free(rpath);
		repo->is_remote = true;
	} else {
		/* local repository */
		repofile = xbps_repo_path(xhp, url);
	}
	/*
	 * In memory repo sync.
	 */
	if (xhp->flags & XBPS_FLAG_REPOS_MEMSYNC) {
		if (repo_open_remote(repo))
			return repo;

		goto out;
	}
	/*
	 * Open the repository archive.
	 */
	repo->fd = open(repofile, O_RDONLY|O_CLOEXEC);
	if (repo->fd == -1) {
		int rv = errno;
		xbps_dbg_printf(xhp, "[repo] `%s' open repodata %s\n",
		    repofile, strerror(rv));
		goto out;
	}
	if (repo_open_local(repo, repofile)) {
		free(repofile);
		return repo;
	}

out:
	free(repofile);
	xbps_repo_close(repo);
	return NULL;
}