Пример #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;
}
Пример #2
0
int
exec_transaction(struct xbps_handle *xhp, int maxcols, bool yes, bool drun)
{
	xbps_array_t array;
	struct transaction *trans;
	uint64_t fsize = 0, isize = 0;
	char freesize[8], instsize[8];
	int rv = 0;

	trans = calloc(1, sizeof(*trans));
	if (trans == NULL)
		return ENOMEM;

	if ((rv = xbps_transaction_prepare(xhp)) != 0) {
		if (rv == ENODEV) {
			array = xbps_dictionary_get(xhp->transd, "missing_deps");
			if (xbps_array_count(array)) {
				/* missing dependencies */
				print_array(array);
				fprintf(stderr, "Transaction aborted due to unresolved dependencies.\n");
			}
		} else if (rv == ENOEXEC) {
			array = xbps_dictionary_get(xhp->transd, "missing_shlibs");
			if (xbps_array_count(array)) {
				/* missing shlibs */
				print_array(array);
				fprintf(stderr, "Transaction aborted due to unresolved shlibs.\n");
			}
		} else if (rv == EAGAIN) {
			/* conflicts */
			array = xbps_dictionary_get(xhp->transd, "conflicts");
			print_array(array);
			fprintf(stderr, "Transaction aborted due to conflicting packages.\n");
		} else if (rv == ENOSPC) {
			/* not enough free space */
			xbps_dictionary_get_uint64(xhp->transd,
			    "total-installed-size", &isize);
			if (xbps_humanize_number(instsize, (int64_t)isize) == -1) {
				xbps_error_printf("humanize_number2 returns "
					"%s\n", strerror(errno));
				return -1;
			}
			xbps_dictionary_get_uint64(xhp->transd,
			    "disk-free-size", &fsize);
			if (xbps_humanize_number(freesize, (int64_t)fsize) == -1) {
				xbps_error_printf("humanize_number2 returns "
					"%s\n", strerror(errno));
				return -1;
			}
			fprintf(stderr, "Transaction aborted due to insufficient disk "
			    "space (need %s, got %s free).\n", instsize, freesize);
		} else {
			xbps_dbg_printf(xhp, "Empty transaction dictionary: %s\n",
			    strerror(errno));
		}
		goto out;
	}
#ifdef FULL_DEBUG
	xbps_dbg_printf(xhp, "Dictionary before transaction happens:\n");
	xbps_dbg_printf_append(xhp, "%s",
	    xbps_dictionary_externalize(xhp->transd));
#endif

	trans->xhp = xhp;
	trans->d = xhp->transd;
	trans->iter = xbps_array_iter_from_dict(xhp->transd, "packages");
	assert(trans->iter);

	/*
	 * dry-run mode, show what would be done but don't run anything.
	 */
	if (drun) {
		show_actions(trans->iter);
		goto out;
	}
	/*
	 * Show download/installed size for the transaction.
	 */
	if ((rv = show_transaction_sizes(trans, maxcols)) != 0)
		goto out;
	/*
	 * Ask interactively (if -y not set).
	 */
	if (!yes && !yesno("Do you want to continue?")) {
		printf("Aborting!\n");
		goto out;
	}
	/*
	 * It's time to run the transaction!
	 */
	if ((rv = xbps_transaction_commit(xhp)) == 0) {
		printf("\n%u downloaded, %u installed, %u updated, "
		    "%u configured, %u removed.\n",
		    trans->dl_pkgcnt, trans->inst_pkgcnt,
		    trans->up_pkgcnt, trans->cf_pkgcnt + trans->inst_pkgcnt,
		    trans->rm_pkgcnt);
	}
out:
	if (trans->iter)
		xbps_object_iterator_release(trans->iter);
	if (trans)
		free(trans);
	return rv;
}
Пример #3
0
int
exec_transaction(struct xbps_handle *xhp, int maxcols, bool yes, bool drun)
{
	xbps_array_t mdeps, cflicts;
	struct transaction *trans;
	int rv = 0;

	trans = calloc(1, sizeof(*trans));
	if (trans == NULL)
		return ENOMEM;

	if ((rv = xbps_transaction_prepare(xhp)) != 0) {
		if (rv == ENODEV) {
			mdeps =
			    xbps_dictionary_get(xhp->transd, "missing_deps");
			/* missing packages */
			show_missing_deps(mdeps);
			fprintf(stderr, "Transaction aborted due to missing/conflicting packages.\n");
			goto out;
		} else if (rv == EAGAIN) {
			/* conflicts */
			cflicts = xbps_dictionary_get(xhp->transd, "conflicts");
			show_conflicts(cflicts);
			fprintf(stderr, "Transaction aborted due to missing/conflicting packages.\n");
			goto out;
		}
		xbps_dbg_printf(xhp, "Empty transaction dictionary: %s\n",
		    strerror(errno));
		return rv;
	}
	xbps_dbg_printf(xhp, "Dictionary before transaction happens:\n");
	xbps_dbg_printf_append(xhp, "%s",
	    xbps_dictionary_externalize(xhp->transd));

	trans->d = xhp->transd;
	trans->iter = xbps_array_iter_from_dict(xhp->transd, "packages");
	assert(trans->iter);

	/*
	 * dry-run mode, show what would be done but don't run anything.
	 */
	if (drun) {
		show_actions(trans->iter);
		goto out;
	}
	/*
	 * Show download/installed size for the transaction.
	 */
	if ((rv = show_transaction_sizes(trans, maxcols)) != 0)
		goto out;
	/*
	 * Ask interactively (if -y not set).
	 */
	if (!yes && !yesno("Do you want to continue?")) {
		printf("Aborting!\n");
		goto out;
	}
	/*
	 * It's time to run the transaction!
	 */
	if ((rv = xbps_transaction_commit(xhp)) == 0) {
		printf("\n%u installed, %u updated, "
		    "%u configured, %u removed.\n", trans->inst_pkgcnt,
		    trans->up_pkgcnt, trans->cf_pkgcnt + trans->inst_pkgcnt,
		    trans->rm_pkgcnt);
	}
out:
	if (trans->iter)
		xbps_object_iterator_release(trans->iter);
	if (trans)
		free(trans);
	return rv;
}