Example #1
0
static void
add_missing_dep(struct pkg_dep *d, struct deps_head *dh, int *nbpkgs)
{
	struct deps_entry *e = NULL;
	const char *origin = NULL;

	assert(d != NULL);

	/* do not add duplicate entries in the queue */
	origin = pkg_dep_origin(d);

	STAILQ_FOREACH(e, dh, next)
		if (strcmp(e->origin, origin) == 0)
			return;

	if ((e = calloc(1, sizeof(struct deps_entry))) == NULL)
		err(1, "calloc(deps_entry)");

	e->name = strdup(pkg_dep_name(d));
	e->version = strdup(pkg_dep_version(d));
	e->origin = strdup(pkg_dep_origin(d));

	(*nbpkgs)++;

	STAILQ_INSERT_TAIL(dh, e, next);
}
Example #2
0
int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL;
	int *debug = data;
	(void) debug;
	const char *filename;
	struct pkg_event_conflict *cur_conflict;

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg,
		    strerror(ev->e_errno.no));
		break;
	case PKG_EVENT_ERROR:
		warnx("%s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_NOTICE:
		if (!quiet)
			warnx("%s", ev->e_pkg_notice.msg);
		break;
	case PKG_EVENT_DEVELOPER_MODE:
		warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_FETCHING:
		if (quiet || !isatty(fileno(stdin)))
			break;
		if (fetched == 0) {
			filename = strrchr(ev->e_fetching.url, '/');
			if (filename != NULL) {
				filename++;
			} else {
				/*
				 * We failed at being smart, so display
				 * the entire url.
				 */
				filename = ev->e_fetching.url;
			}
			strlcpy(url, filename, sizeof(url));
			start_progress_meter(url, ev->e_fetching.total,
			    &fetched);
		}
		fetched = ev->e_fetching.done;
		if (ev->e_fetching.done == ev->e_fetching.total) {
			stop_progress_meter();
			fetched = 0;
		}
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		if (quiet)
			break;
		else {
			struct sbuf	*msg;

			nbdone++;

			msg = sbuf_new_auto();
			if (msg == NULL) {
				warn("sbuf_new_auto() failed");
				break;
			}

			print_status_begin(msg);

			pkg = ev->e_install_begin.pkg;
			pkg_sbuf_printf(msg, "Installing %n-%v...", pkg, pkg);

			print_status_end(msg);
		}
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		if (pkg_has_message(ev->e_install_finished.pkg)) {
			if (messages == NULL)
				messages = sbuf_new_auto();
			pkg_sbuf_printf(messages, "%M\n",
			    ev->e_install_finished.pkg);
		}
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		if (quiet)
			break;
		printf("Checking integrity...");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
		printf("\nConflict found on path %s between %s-%s(%s) and ",
		    ev->e_integrity_conflict.pkg_path,
		    ev->e_integrity_conflict.pkg_name,
		    ev->e_integrity_conflict.pkg_version,
		    ev->e_integrity_conflict.pkg_origin);
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict) {
			if (cur_conflict->next)
				printf("%s-%s(%s), ", cur_conflict->name,
				    cur_conflict->version,
				    cur_conflict->origin);
			else
				printf("%s-%s(%s)", cur_conflict->name,
				    cur_conflict->version,
				    cur_conflict->origin);

			cur_conflict = cur_conflict->next;
		}
		printf("\n");
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		if (quiet)
			break;
		else {
			struct sbuf	*msg;

			nbdone++;

			msg = sbuf_new_auto();
			if (msg == NULL) {
				warn("sbuf_new_auto() failed");
				break;
			}

			print_status_begin(msg);

			pkg = ev->e_install_begin.pkg;
			pkg_sbuf_printf(msg, "Deleting %n-%v...", pkg, pkg);

			print_status_end(msg);
		}
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		if (quiet)
			break;
		else {
			struct sbuf	*msg;

			pkg = ev->e_upgrade_begin.pkg;
			nbdone++;

			msg = sbuf_new_auto();
			if (msg == NULL) {
				warn("sbuf_new_auto() failed");
				break;
			}

			print_status_begin(msg);

			switch (pkg_version_change(pkg)) {
			case PKG_DOWNGRADE:
				pkg_sbuf_printf(msg,
				    "Downgrading %n from %V to %v...",
				    pkg, pkg, pkg);
				break;
			case PKG_REINSTALL:
				pkg_sbuf_printf(msg, "Reinstalling %n-%V...",
				    pkg, pkg);
				break;
			case PKG_UPGRADE:
				pkg_sbuf_printf(msg,
				    "Upgrading %n from %V to %v...",
						pkg, pkg, pkg);
				break;
			}
			print_status_end(msg);
		}
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		if (pkg_has_message(ev->e_upgrade_finished.pkg)) {
			if (messages == NULL)
				messages = sbuf_new_auto();
			pkg_sbuf_printf(messages, "%M\n",
			    ev->e_upgrade_finished.pkg);
		}
		break;
	case PKG_EVENT_LOCKED:
		pkg = ev->e_locked.pkg;
		pkg_fprintf(stderr,
		    "\n%n-%v is locked and may not be modified\n",
		    pkg, pkg);
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		pkg_fprintf(stderr,
		    "\n%n-%v is required by: %r%{%rn-%rv%| %}",
		    pkg, pkg, pkg);
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		if (quiet)
			break;
		pkg = ev->e_already_installed.pkg;
		pkg_printf("%n-%v already installed\n", pkg, pkg);
		break;
	case PKG_EVENT_NOT_FOUND:
		printf("Package '%s' was not found in "
		    "the repositories\n", ev->e_not_found.pkg_name);
		break;
	case PKG_EVENT_MISSING_DEP:
		fprintf(stderr, "missing dependency %s-%s\n",
		    pkg_dep_name(ev->e_missing_dep.dep),
		    pkg_dep_version(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		fprintf(stderr, "Unable to open remote database \"%s\". "
		    "Try running '%s update' first.\n", ev->e_remotedb.repo,
		    getprogname());
		break;
	case PKG_EVENT_NOLOCALDB:
		fprintf(stderr, "Local package database nonexistent!\n");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		newpkgversion = true;
		printf("New version of pkg detected; it needs to be "
		    "installed first.\n");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg = ev->e_file_mismatch.pkg;
		pkg_fprintf(stderr, "%n-%v: checksum mismatch for %S\n", pkg,
		    pkg, pkg_file_path(ev->e_file_mismatch.file));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
		warnx("%s: %s(%s): %s",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_errno.func, ev->e_plugin_errno.arg,
		    strerror(ev->e_plugin_errno.no));
		break;
	case PKG_EVENT_PLUGIN_ERROR:
		warnx("%s: %s",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_error.msg);
		break;
	case PKG_EVENT_PLUGIN_INFO:
		if (quiet)
			break;
		printf("%s: %s\n",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_info.msg);
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
		if (!quiet)
			printf("Incremental update completed, %d packages "
			    "processed:\n"
			    "%d packages updated, %d removed and %d added.\n",
			    ev->e_incremental_update.processed,
			    ev->e_incremental_update.updated,
			    ev->e_incremental_update.removed,
			    ev->e_incremental_update.added);
		break;
	case PKG_EVENT_DEBUG:
		fprintf(stderr, "DBG(%d)> %s\n", ev->e_debug.level, ev->e_debug.msg);
		break;
	default:
		break;
	}

	return 0;
}
Example #3
0
static int
convert_to_old(const char *pkg_add_dbdir, bool dry_run)
{
	struct pkgdb *db = NULL;
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it = NULL;
	char *content, *name, *version, *buf;
	const char *tmp;
	int ret = EX_OK;
	char path[MAXPATHLEN];
	int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
	    PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
	    PKG_LOAD_OPTIONS | PKG_LOAD_MTREE |
	    PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_RDEPS;
	FILE *fp, *rq;
	struct sbuf *install_script = sbuf_new_auto();
	struct sbuf *deinstall_script = sbuf_new_auto();

	if (mkdir(pkg_add_dbdir, 0755) != 0 && errno != EEXIST)
		err(EX_CANTCREAT, "%s", pkg_add_dbdir);

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	while (pkgdb_it_next(it, &pkg, query_flags) == EPKG_OK) {
		rq = NULL;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("Converting %s-%s...", name, version);
		if (dry_run) {
			printf("\n");
			continue;
		}
		pkg_to_old(pkg);
		pkg_old_emit_content(pkg, &content);

		snprintf(path, MAXPATHLEN, "%s/%s-%s", pkg_add_dbdir, name, version);
		mkdir(path, 0755);

		snprintf(path, MAXPATHLEN, "%s/%s-%s/+CONTENTS", pkg_add_dbdir, name, version);
		fp = fopen(path, "w");
		fputs(content, fp);
		fclose(fp);

		pkg_get(pkg, PKG_DESC, &buf);
		snprintf(path, MAXPATHLEN, "%s/%s-%s/+DESC", pkg_add_dbdir, name, version);
		fp = fopen(path, "w");
		fputs(buf, fp);
		fclose(fp);

		pkg_get(pkg, PKG_COMMENT, &buf);
		snprintf(path, MAXPATHLEN, "%s/%s-%s/+COMMENT", pkg_add_dbdir, name, version);
		fp = fopen(path, "w");
		fprintf(fp, "%s\n", buf);
		fclose(fp);

		pkg_get(pkg, PKG_MESSAGE, &buf);
		if (buf != NULL && buf[0] != '\0') {
			snprintf(path, MAXPATHLEN, "%s/%s-%s/+DISPLAY", pkg_add_dbdir, name, version);
			fp = fopen(path, "w");
			fputs(buf, fp);
			fclose(fp);
		}

		pkg_get(pkg, PKG_MTREE, &buf);
		if (buf != NULL && buf[0] != '\0') {
			snprintf(path, MAXPATHLEN, "%s/%s-%s/+MTREE_DIRS", pkg_add_dbdir, name, version);
			fp = fopen(path, "w");
			fputs(buf, fp);
			fclose(fp);
		}

		sbuf_clear(install_script);
		tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(install_script) == 0)
				sbuf_cat(install_script, "#!/bin/sh\n\n");
			sbuf_printf(install_script,
			    "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n"
			    "%s\n"
			    "fi\n",
			    tmp);
		}

		tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(install_script) == 0)
				sbuf_cat(install_script, "#!/bin/sh\n\n");
			sbuf_cat(install_script, tmp);
		}

		tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(install_script) == 0)
				sbuf_cat(install_script, "#!/bin/sh\n\n");
			sbuf_printf(install_script,
			    "if [ \"$2\" = \"POST-INSTALL\" ]; then\n"
			    "%s\n"
			    "fi\n",
			    tmp);
		}
		if (sbuf_len(install_script) > 0) {
			sbuf_finish(install_script);
			snprintf(path, MAXPATHLEN, "%s/%s-%s/+INSTALL", pkg_add_dbdir, name, version);
			fp = fopen(path, "w");
			fputs(sbuf_data(install_script), fp);
			fclose(fp);
		}

		sbuf_clear(deinstall_script);
		tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(deinstall_script) == 0)
				sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
			sbuf_printf(deinstall_script,
			    "if [ \"$2\" = \"DEINSTALL\" ]; then\n"
			    "%s\n"
			    "fi\n",
			    tmp);
		}

		tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(deinstall_script) == 0)
				sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
			sbuf_cat(deinstall_script, tmp);
		}

		tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL);
		if (tmp != NULL && tmp[0] != '\0') {
			if (sbuf_len(deinstall_script) == 0)
				sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
			sbuf_printf(deinstall_script,
			    "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n"
			    "%s\n"
			    "fi\n",
			    tmp);
		}
		if (sbuf_len(deinstall_script) > 0) {
			sbuf_finish(deinstall_script);
			snprintf(path, MAXPATHLEN, "%s/%s-%s/+DEINSTALL", pkg_add_dbdir, name, version);
			fp = fopen(path, "w");
			fputs(sbuf_data(deinstall_script), fp);
			fclose(fp);
		}

		snprintf(path, MAXPATHLEN, "%s/%s-%s/+REQUIRED_BY", pkg_add_dbdir, name, version);
		while (pkg_rdeps(pkg, &dep) == EPKG_OK) {
			if (rq == NULL)
				rq = fopen(path, "w");
			fprintf(rq, "%s-%s\n", pkg_dep_name(dep), pkg_dep_version(dep));
		}
		if (rq != NULL)
			fclose(rq);
		printf("done.\n");

		free(content);
	}
	sbuf_delete(install_script);
	sbuf_delete(deinstall_script);

cleanup:
	pkg_free(pkg);
	pkgdb_it_free(it);
	pkgdb_close(db);

	return (ret);
}
Example #4
0
int
pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *data)
{
	FTS *fts = NULL;
	FTSENT *ent = NULL;

	struct stat st;
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_category *category = NULL;
	struct pkg_license *license = NULL;
	struct pkg_option *option = NULL;
	struct sbuf *manifest = sbuf_new_auto();
	char *ext = NULL;

	sqlite3 *sqlite = NULL;
	sqlite3_stmt *stmt_deps = NULL;
	sqlite3_stmt *stmt_pkg = NULL;
	sqlite3_stmt *stmt_lic1 = NULL;
	sqlite3_stmt *stmt_lic2 = NULL;
	sqlite3_stmt *stmt_cat1 = NULL;
	sqlite3_stmt *stmt_cat2 = NULL;
	sqlite3_stmt *stmt_opts = NULL;

	int64_t package_id;
	char *errmsg = NULL;
	int retcode = EPKG_OK;
	char *pkg_path;
	char cksum[SHA256_DIGEST_LENGTH * 2 +1];

	char *repopath[2];
	char repodb[MAXPATHLEN + 1];

	const char initsql[] = ""
		"CREATE TABLE packages ("
			"id INTEGER PRIMARY KEY,"
			"origin TEXT UNIQUE,"
			"name TEXT NOT NULL,"
			"version TEXT NOT NULL,"
			"comment TEXT NOT NULL,"
			"desc TEXT NOT NULL,"
			"arch TEXT NOT NULL,"
			"osversion TEXT NOT NULL,"
			"maintainer TEXT NOT NULL,"
			"www TEXT,"
			"prefix TEXT NOT NULL,"
			"pkgsize INTEGER NOT NULL,"
			"flatsize INTEGER NOT NULL,"
			"licenselogic INTEGER NOT NULL,"
			"cksum TEXT NOT NULL,"
			"path TEXT NOT NULL," /* relative path to the package in the repository */
			"pkg_format_version INTEGER"
		");"
		"CREATE TABLE deps ("
			"origin TEXT,"
			"name TEXT,"
			"version TEXT,"
			"package_id INTEGER REFERENCES packages(id),"
			"UNIQUE(package_id, origin)"
		");"
		"CREATE TABLE categories ("
			"id INTEGER PRIMARY KEY, "
			"name TEXT NOT NULL UNIQUE "
		");"
		"CREATE TABLE pkg_categories ("
			"package_id INTEGER REFERENCES packages(id), "
			"category_id INTEGER REFERENCES categories(id), "
			"UNIQUE(package_id, category_id)"
		");"
		"CREATE TABLE licenses ("
			"id INTEGER PRIMARY KEY,"
			"name TEXT NOT NULL UNIQUE"
		");"
		"CREATE TABLE pkg_licenses ("
			"package_id INTEGER REFERENCES packages(id), "
			"license_id INTEGER REFERENCES licenses(id), "
			"UNIQUE(package_id, license_id)"
		");"
		"CREATE TABLE options ("
			"package_id INTEGER REFERENCES packages(id), "
			"option TEXT,"
			"value TEXT,"
			"UNIQUE (package_id, option)"
		");"
		"PRAGMA user_version=2;"
		;
	const char pkgsql[] = ""
		"INSERT INTO packages ("
				"origin, name, version, comment, desc, arch, osversion, "
				"maintainer, www, prefix, pkgsize, flatsize, licenselogic, cksum, path"
		")"
		"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15);";
	const char depssql[] = ""
		"INSERT INTO deps (origin, name, version, package_id) "
		"VALUES (?1, ?2, ?3, ?4);";
	const char licsql[] = "INSERT OR IGNORE INTO licenses(name) VALUES(?1);";
	const char addlicsql[] = "INSERT OR ROLLBACK INTO pkg_licenses(package_id, license_id) "
		"VALUES (?1, (SELECT id FROM licenses WHERE name = ?2));";
	const char catsql[] = "INSERT OR IGNORE INTO categories(name) VALUES(?1);";
	const char addcatsql[] = "INSERT OR ROLLBACK INTO pkg_categories(package_id, category_id) "
		"VALUES (?1, (SELECT id FROM categories WHERE name = ?2));";
	const char addoption[] = "INSERT OR ROLLBACK INTO options (option, value, package_id) "
		"VALUES (?1, ?2, ?3);";

	if (!is_dir(path)) {
		pkg_emit_error("%s is not a directory", path);
		return EPKG_FATAL;
	}

	repopath[0] = path;
	repopath[1] = NULL;

	snprintf(repodb, sizeof(repodb), "%s/repo.sqlite", path);

	if (stat(repodb, &st) != -1)
		if (unlink(repodb) != 0) {
			pkg_emit_errno("unlink", path);
			return EPKG_FATAL;
		}

	sqlite3_initialize();
	if (sqlite3_open(repodb, &sqlite) != SQLITE_OK) {
		sqlite3_shutdown();
		return (EPKG_FATAL);
	}
	
	if ((retcode = sql_exec(sqlite, initsql)) != EPKG_OK)
		goto cleanup;

	if ((retcode = sql_exec(sqlite, "BEGIN TRANSACTION;")) != EPKG_OK)
		goto cleanup;

	if (sqlite3_prepare_v2(sqlite, pkgsql, -1, &stmt_pkg, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, depssql, -1, &stmt_deps, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, licsql, -1, &stmt_lic1, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addlicsql, -1, &stmt_lic2, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addoption, -1, &stmt_opts, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((fts = fts_open(repopath, FTS_PHYSICAL, NULL)) == NULL) {
		pkg_emit_errno("fts_open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, catsql, -1, &stmt_cat1, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addcatsql, -1, &stmt_cat2, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	while ((ent = fts_read(fts)) != NULL) {
		cksum[0] = '\0';
		/* skip everything that is not a file */
		if (ent->fts_info != FTS_F)
			continue;

		ext = strrchr(ent->fts_name, '.');

		if (ext == NULL)
			continue;

		if (strcmp(ext, ".tgz") != 0 &&
				strcmp(ext, ".tbz") != 0 &&
				strcmp(ext, ".txz") != 0 &&
				strcmp(ext, ".tar") != 0)
			continue;

		pkg_path = ent->fts_path;
		pkg_path += strlen(path);
		while (pkg_path[0] == '/' )
			pkg_path++;

		if (pkg_open(&pkg, ent->fts_accpath, manifest) != EPKG_OK) {
			retcode = EPKG_WARN;
			continue;
		}
		if (progress != NULL)
			progress(pkg, data);

		sqlite3_bind_text(stmt_pkg, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 2, pkg_get(pkg, PKG_NAME), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 3, pkg_get(pkg, PKG_VERSION), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 4, pkg_get(pkg, PKG_COMMENT), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 5, pkg_get(pkg, PKG_DESC), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 6, pkg_get(pkg, PKG_ARCH), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 7, pkg_get(pkg, PKG_OSVERSION), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 8, pkg_get(pkg, PKG_MAINTAINER), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 9, pkg_get(pkg, PKG_WWW), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 10, pkg_get(pkg, PKG_PREFIX), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_pkg, 11, ent->fts_statp->st_size);
		sqlite3_bind_int64(stmt_pkg, 12, pkg_flatsize(pkg));
		sha256_file(ent->fts_accpath, cksum);
		sqlite3_bind_int64(stmt_pkg, 13, pkg_licenselogic(pkg));
		sqlite3_bind_text(stmt_pkg, 14, cksum, -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 15, pkg_path, -1, SQLITE_STATIC);

		if (sqlite3_step(stmt_pkg) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
		sqlite3_reset(stmt_pkg);

		package_id = sqlite3_last_insert_rowid(sqlite);

		dep = NULL;
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			sqlite3_bind_text(stmt_deps, 1, pkg_dep_origin(dep), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_deps, 2, pkg_dep_name(dep), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_deps, 3, pkg_dep_version(dep), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_deps, 4, package_id);

			if (sqlite3_step(stmt_deps) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_deps);
		}

		category = NULL;
		while (pkg_categories(pkg, &category) == EPKG_OK) {
			sqlite3_bind_text(stmt_cat1, 1, pkg_category_name(category), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_cat2, 1, package_id);
			sqlite3_bind_text(stmt_cat2, 2, pkg_category_name(category), -1, SQLITE_STATIC);

			if (sqlite3_step(stmt_cat1) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}

			if (sqlite3_step(stmt_cat2) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_cat1);
			sqlite3_reset(stmt_cat2);
		}

		license = NULL;
		while (pkg_licenses(pkg, &license) == EPKG_OK) {
			sqlite3_bind_text(stmt_lic1, 1, pkg_license_name(license), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_lic2, 1, package_id);
			sqlite3_bind_text(stmt_lic2, 2, pkg_license_name(license), -1, SQLITE_STATIC);

			if (sqlite3_step(stmt_lic1) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}

			if (sqlite3_step(stmt_lic2) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_lic1);
			sqlite3_reset(stmt_lic2);
		}
		option = NULL;
		while (pkg_options(pkg, &option) == EPKG_OK) {
			sqlite3_bind_text(stmt_opts, 1, pkg_option_opt(option), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_opts, 2, pkg_option_value(option), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_opts, 3, package_id);

			if (sqlite3_step(stmt_opts) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_opts);
		}
	}

	if (sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, &errmsg) != SQLITE_OK) {
		pkg_emit_error("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
	}

	cleanup:
	if (fts != NULL)
		fts_close(fts);

	if (pkg != NULL)
		pkg_free(pkg);

	if (stmt_pkg != NULL)
		sqlite3_finalize(stmt_pkg);

	if (stmt_deps != NULL)
		sqlite3_finalize(stmt_deps);

	if (stmt_cat1 != NULL)
		sqlite3_finalize(stmt_cat1);

	if (stmt_cat2 != NULL)
		sqlite3_finalize(stmt_cat2);

	if (stmt_lic1 != NULL)
		sqlite3_finalize(stmt_lic1);

	if (stmt_lic2 != NULL)
		sqlite3_finalize(stmt_lic2);

	if (stmt_opts != NULL)
		sqlite3_finalize(stmt_opts);

	if (sqlite != NULL)
		sqlite3_close(sqlite);

	if (errmsg != NULL)
		sqlite3_free(errmsg);

	sbuf_delete(manifest);

	sqlite3_shutdown();

	return (retcode);
}
Example #5
0
File: event.c Project: gsamat/pkgng
int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	const char *message;
	int *debug = data;
	(void) debug;
	const char *name, *version, *newversion;
	const char *filename;

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg);
		break;
	case PKG_EVENT_ERROR:
		warnx("%s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_FETCHING:
		if (quiet)
			break;
		if (fetched == 0) {
			filename = strrchr(ev->e_fetching.url, '/');
			if (filename != NULL) {
				filename++;
			} else {
				/*
				 * We failed at being smart, so display
				 * the entire url.
				 */
				filename = ev->e_fetching.url;
			}
			strlcpy(url, filename, sizeof(url));
			start_progress_meter(url, ev->e_fetching.total,
			    &fetched);
		}
		fetched = ev->e_fetching.done;
		if (ev->e_fetching.done == ev->e_fetching.total) {
			stop_progress_meter();
			fetched = 0;
		}
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		printf("Installing %s-%s...", name, version);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message);
		if (message != NULL && message[0] != '\0') {
			if (messages == NULL)
				messages = sbuf_new_auto();
			sbuf_printf(messages, "%s\n", message);
		}
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		if (quiet)
			break;
		printf("Checking integrity...");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		printf("Deinstalling %s-%s...", name, version);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version, PKG_NEWVERSION, &newversion);
		switch (pkg_version_cmp(version, newversion)) {
		case 1:
			printf("Downgrading %s from %s to %s...", name,
			    version, newversion);
			break;
		case 0:
			printf("Reinstalling %s-%s", name, version);
			break;
		case -1:
			printf("Upgrading %s from %s to %s...", name,
			    version, newversion);
			break;
		}
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		fprintf(stderr, "%s-%s is required by:", name, version);
		while (pkg_rdeps(pkg, &dep) == EPKG_OK)
			fprintf(stderr, " %s-%s", pkg_dep_name(dep),
			    pkg_dep_version(dep));
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		if (quiet)
			break;
		pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		printf("%s-%s already installed\n", name, version);
		break;
	case PKG_EVENT_MISSING_DEP:
		fprintf(stderr, "missing dependency %s-%s",
		    pkg_dep_name(ev->e_missing_dep.dep),
		    pkg_dep_version(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		fprintf(stderr, "Unable to open remote database \"%s\". "
		    "Try running '%s update' first.\n", ev->e_remotedb.repo,
		    getprogname());
		break;
	case PKG_EVENT_NOLOCALDB:
		/* only cares if run as root */
		if (geteuid() == 0)
			fprintf(stderr, "Unable to create local database!\n");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		printf("New version of pkg detected; it needs to be "
		    "installed first.\nAfter this upgrade it is recommended"
		    "that you do a full upgrade using: 'pkg upgrade'\n\n");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name,
		    version, pkg_file_path(ev->e_file_mismatch.file));
	default:
		break;
	}

	return 0;
}
Example #6
0
File: utils.c Project: varju/pkgng
void
print_info(struct pkg * const pkg, unsigned int options)
{
	struct pkg_category *cat    = NULL;
	struct pkg_dep	    *dep    = NULL;
	struct pkg_dir	    *dir    = NULL;
	struct pkg_file	    *file   = NULL;
	struct pkg_group    *group  = NULL;
	struct pkg_license  *lic    = NULL;
	struct pkg_option   *option = NULL;
	struct pkg_shlib    *shlib  = NULL;
	struct pkg_user	    *user   = NULL;
	bool multirepos_enabled = false;
	bool print_tag = false;
	bool show_locks = false;
	char size[7];
	const char *name, *version, *prefix, *origin, *reponame, *repourl;
	const char *maintainer, *www, *comment, *desc, *message, *arch;
	const char *repopath;
	const char *tab;
	char *m;
	unsigned opt;
	int64_t flatsize, newflatsize, newpkgsize;
	lic_t licenselogic;
	bool locked;
	int cout = 0;		/* Number of characters output */
	int info_num;		/* Number of different data items to print */

	pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled);

	pkg_get(pkg,
		PKG_NAME,          &name,
		PKG_VERSION,       &version,
		PKG_PREFIX,        &prefix,
		PKG_ORIGIN,        &origin,
		PKG_REPONAME,      &reponame,
		PKG_REPOURL,       &repourl,
		PKG_MAINTAINER,    &maintainer,
		PKG_WWW,           &www,
		PKG_COMMENT,       &comment,
		PKG_DESC,          &desc,
		PKG_FLATSIZE,      &flatsize,
		PKG_NEW_FLATSIZE,  &newflatsize,
		PKG_NEW_PKGSIZE,   &newpkgsize,
		PKG_LICENSE_LOGIC, &licenselogic,
		PKG_MESSAGE,       &message,
		PKG_ARCH,	   &arch,
		PKG_REPOPATH,	   &repopath,
		PKG_LOCKED,	   &locked);

	if (!multirepos_enabled)
		pkg_config_string(PKG_CONFIG_REPO, &repourl);

	if (options & INFO_RAW) { /* Not for remote packages */
		if (pkg_type(pkg) != PKG_REMOTE) {
			pkg_emit_manifest(pkg, &m);
			printf("%s\n", m);
			free(m);
		}
		return;
	}

	/* Show locking status when requested to display it and the
	   package is locally installed */
	if (pkg_type(pkg) == PKG_INSTALLED && (options & INFO_LOCKED) != 0)
		show_locks = true;

	if (!quiet) {
		/* Print a tag-line identifying the package -- either
		   NAMEVER, ORIGIN or NAME (in that order of
		   preference).  This may be the only output from this
		   function */

		if (options & INFO_TAG_NAMEVER)
			cout = printf("%s-%s", name, version);
		else if (options & INFO_TAG_ORIGIN)
			cout = printf("%s", origin);
		else if (options & INFO_TAG_NAME)
			cout = printf("%s", name);
	}

	/* Don't display a tab if quiet, retains compatibility. */
	tab = quiet ? "" : "\t";

	/* If we printed a tag, and there are no other items to print,
	   then just return now. If there's only one single-line item
	   to print, show it at column 32 on the same line. If there's
	   one multi-line item to print, start a new line. If there is
	   more than one item to print per pkg, use 'key : value'
	   style to show on a new line.  */

	info_num = 0;
	for (opt = 0x1U; opt <= INFO_LASTFIELD; opt <<= 1) 
		if ((opt & options) != 0)
			info_num++;

	if (info_num == 0 && cout > 0) {
		printf("\n");
		return;
	}

	if (info_num == 1) {
		/* Only one item to print */
		print_tag = false;
		if (!quiet) {
			if (options & INFO_MULTILINE)
				printf(":\n");
			else {
				if (cout < 31)
					cout = 31 - cout;
				else
					cout = 1;
				printf("%*s", cout, " ");
			}
		}
	} else {
		/* Several items to print */
		print_tag = true;
		if (!quiet)
			printf("\n");
	}

	for (opt = 0x1; opt <= INFO_LASTFIELD; opt <<= 1) {
		if ((opt & options) == 0)
			continue;

		switch (opt) {
		case INFO_NAME:
			if (print_tag)
				printf("%-15s: ", "Name");
			printf("%s\n", name);
			break;
		case INFO_VERSION:
			if (print_tag)
				printf("%-15s: ", "Version");
			printf("%s\n", version);
			break;
		case INFO_ORIGIN:
			if (print_tag)
				printf("%-15s: ", "Origin");
			printf("%s\n", origin);
			break;
		case INFO_PREFIX:
			if (print_tag)
				printf("%-15s: ", "Prefix");
			printf("%s\n", prefix);
			break;
		case INFO_REPOSITORY:
			if (pkg_type(pkg) == PKG_REMOTE &&
			    repourl != NULL && repourl[0] != '\0') {
				if (print_tag)
					printf("%-15s: ", "Repository");
				printf("%s [%s]\n", reponame, repourl);
			} else if (!print_tag)
				printf("\n");
			break;
		case INFO_CATEGORIES:
			if (pkg_list_count(pkg, PKG_CATEGORIES) > 0) {
				if (print_tag)
					printf("%-15s: ", "Categories");
				if (pkg_categories(pkg, &cat) == EPKG_OK)
					printf("%s", pkg_category_name(cat));
				while (pkg_categories(pkg, &cat) == EPKG_OK)
					printf(" %s", pkg_category_name(cat));
				printf("\n");
			} else if (!print_tag)
				printf("\n");
			break;
		case INFO_LICENSES:
			if (pkg_list_count(pkg, PKG_LICENSES) > 0) {
				if (print_tag)
					printf("%-15s: ", "Licenses");
				if (pkg_licenses(pkg, &lic) == EPKG_OK)
					printf("%s", pkg_license_name(lic));
				while (pkg_licenses(pkg, &lic) == EPKG_OK) {
					if (licenselogic != 1)
						printf(" %c", licenselogic);
					printf(" %s", pkg_license_name(lic));
				}
				printf("\n");				
			} else if (!print_tag)
				printf("\n");
			break;
		case INFO_MAINTAINER:
			if (print_tag)
				printf("%-15s: ", "Maintainer");
			printf("%s\n", maintainer);
			break;
		case INFO_WWW:	
			if (print_tag)
				printf("%-15s: ", "WWW");
			printf("%s\n", www);
			break;
		case INFO_COMMENT:
			if (print_tag)
				printf("%-15s: ", "Comment");
			printf("%s\n", comment);
			break;
		case INFO_OPTIONS:
			if (pkg_list_count(pkg, PKG_OPTIONS) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Options");
				while (pkg_options(pkg, &option) == EPKG_OK)
					printf("%s%-15s: %s\n",
					       tab,
					       pkg_option_opt(option),
					       pkg_option_value(option));
			}
			break;
		case INFO_SHLIBS_REQUIRED:
			if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Shared Libs required");
				while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK)
					printf("%s%s\n", tab, pkg_shlib_name(shlib));
			}
			break;
		case INFO_SHLIBS_PROVIDED:
			if (pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Shared Libs provided");
				while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK)
					printf("%s%s\n", tab, pkg_shlib_name(shlib));
			}
			break;
		case INFO_FLATSIZE:
			if (pkg_type(pkg) == PKG_INSTALLED ||
			    pkg_type(pkg) == PKG_FILE)
				humanize_number(size, sizeof(size),
						flatsize,"B",
						HN_AUTOSCALE, 0);
			else
				humanize_number(size, sizeof(size),
						newflatsize,"B",
						HN_AUTOSCALE, 0);

			if (print_tag)
				printf("%-15s: ", "Flat size");
			printf("%s\n", size);
			break;
		case INFO_PKGSIZE: /* Remote pkgs only */
			if (pkg_type(pkg) == PKG_REMOTE) {
				humanize_number(size, sizeof(size),
						newpkgsize,"B",
						HN_AUTOSCALE, 0);
				if (print_tag)
					printf("%-15s: ", "Pkg size");
				printf("%s\n", size);
			} else if (!print_tag)
				printf("\n");
			break;
		case INFO_DESCR:
			if (print_tag)
				printf("%-15s:\n", "Description");
			printf("%s\n", desc);
			break;
		case INFO_MESSAGE:
			if (message) {
				if (print_tag)
					printf("%-15s:\n", "Message");
				printf("%s\n", message);
			}
			break;
		case INFO_DEPS:
			if (pkg_list_count(pkg, PKG_DEPS) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Depends on");
				while (pkg_deps(pkg, &dep) == EPKG_OK) {
					printf("%s%s-%s",
					       tab,
					       pkg_dep_name(dep),
					       pkg_dep_version(dep));
					if (show_locks && pkg_dep_is_locked(dep))
						printf(" (*)");
					printf("\n");
				}
			}
			break;
		case INFO_RDEPS:
			if (pkg_list_count(pkg, PKG_RDEPS) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Required by");
				while (pkg_rdeps(pkg, &dep) == EPKG_OK) {
					printf("%s%s-%s",
					       tab,
					       pkg_dep_name(dep),
					       pkg_dep_version(dep));
					if (show_locks && pkg_dep_is_locked(dep))
						printf(" (*)");
					printf("\n");
				}
			}
			break;
		case INFO_FILES: /* Installed pkgs only */
			if (pkg_type(pkg) != PKG_REMOTE &&
			    pkg_list_count(pkg, PKG_FILES) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Files");
				while (pkg_files(pkg, &file) == EPKG_OK)
					printf("%s%s\n",
					       tab,
					       pkg_file_path(file));
			}
			break;
		case INFO_DIRS:	/* Installed pkgs only */
			if (pkg_type(pkg) != PKG_REMOTE &&
			    pkg_list_count(pkg, PKG_DIRS) > 0) {
				if (print_tag)
					printf("%-15s:\n", "Directories");
				while (pkg_dirs(pkg, &dir) == EPKG_OK)
					printf("%s%s\n",
					       tab,
					       pkg_dir_path(dir));
			}
			break;
		case INFO_USERS: /* Installed pkgs only */
			if (pkg_type(pkg) != PKG_REMOTE &&
			    pkg_list_count(pkg, PKG_USERS) > 0) {
				if (print_tag)
					printf("%-15s: ", "Users");
				if (pkg_users(pkg, &user) == EPKG_OK)
					printf("%s", pkg_user_name(user));
				while (pkg_users(pkg, &user) == EPKG_OK)
					printf(" %s", pkg_user_name(user));
				printf("\n");
			}
			break;
		case INFO_GROUPS: /* Installed pkgs only */
			if (pkg_type(pkg) != PKG_REMOTE &&
			    pkg_list_count(pkg, PKG_GROUPS) > 0) {
				if (print_tag)
					printf("%-15s: ", "Groups");
				if (pkg_groups(pkg, &group) == EPKG_OK)
					printf("%s", pkg_group_name(group));
				while (pkg_groups(pkg, &group) == EPKG_OK)
					printf(" %s", pkg_group_name(group));
				printf("\n");
			}
			break;
		case INFO_ARCH:
			if (print_tag)
				printf("%-15s: ", "Architecture");
			printf("%s\n", arch);
			break;
		case INFO_REPOURL:
			if (pkg_type(pkg) == PKG_REMOTE &&
			    repourl != NULL && repourl[0] != '\0') {
				if (print_tag)
					printf("%-15s: ", "Pkg URL");
				if (repourl[strlen(repourl) -1] == '/')
					printf("%s%s\n", repourl, repopath);
				else
					printf("%s/%s\n", repourl, repopath);
			} else if (!print_tag)
				printf("\n");
			break;
		case INFO_LOCKED:
			if (print_tag)
				printf("%-15s: ", "Locked");
			printf("%s\n", locked ? "yes" : "no");
			break;
		}
	}
}
Example #7
0
File: update.c Project: zxombie/pkg
static int
pkg_repo_binary_add_pkg(struct pkg *pkg, const char *pkg_path,
		sqlite3 *sqlite, bool forced)
{
	const char *name, *version, *origin, *comment, *desc;
	const char *arch, *maintainer, *www, *prefix, *sum, *rpath;
	const char *olddigest, *manifestdigest;
	int64_t			 flatsize, pkgsize;
	int64_t			 licenselogic;
	int			 ret;
	struct pkg_dep		*dep      = NULL;
	struct pkg_option	*option   = NULL;
	struct pkg_shlib	*shlib    = NULL;
	const pkg_object	*obj, *licenses, *categories, *annotations;
	pkg_iter		 it;
	int64_t			 package_id;

	pkg_get(pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
			    PKG_VERSION, &version, PKG_COMMENT, &comment,
			    PKG_DESC, &desc, PKG_ARCH, &arch,
			    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
			    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
			    PKG_LICENSE_LOGIC, &licenselogic, PKG_CKSUM, &sum,
			    PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &rpath,
			    PKG_LICENSES, &licenses, PKG_CATEGORIES, &categories,
			    PKG_ANNOTATIONS, &annotations, PKG_OLD_DIGEST, &olddigest,
			    PKG_DIGEST, &manifestdigest);

try_again:
	if ((ret = pkg_repo_binary_run_prstatement(PKG, origin, name, version,
			comment, desc, arch, maintainer, www, prefix,
			pkgsize, flatsize, (int64_t)licenselogic, sum,
			rpath, manifestdigest, olddigest)) != SQLITE_DONE) {
		if (ret == SQLITE_CONSTRAINT) {
			switch(pkg_repo_binary_delete_conflicting(origin,
					version, pkg_path, forced)) {
			case EPKG_FATAL: /* sqlite error */
				ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
				return (EPKG_FATAL);
				break;
			case EPKG_END: /* repo already has newer */
				return (EPKG_END);
				break;
			default: /* conflict cleared, try again */
				goto try_again;
				break;
			}
		} else {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
			return (EPKG_FATAL);
		}
	}
	package_id = sqlite3_last_insert_rowid(sqlite);

	if (pkg_repo_binary_run_prstatement (FTS_APPEND, package_id,
			name, version, origin) != SQLITE_DONE) {
		ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(FTS_APPEND));
		return (EPKG_FATAL);
	}

	dep = NULL;
	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (pkg_repo_binary_run_prstatement(DEPS,
				pkg_dep_origin(dep),
				pkg_dep_name(dep),
				pkg_dep_version(dep),
				package_id) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(DEPS));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(categories, &it))) {
		ret = pkg_repo_binary_run_prstatement(CAT1, pkg_object_string(obj));
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(CAT2, package_id,
			    pkg_object_string(obj));
		if (ret != SQLITE_DONE)
		{
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(CAT2));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(licenses, &it))) {
		ret = pkg_repo_binary_run_prstatement(LIC1, pkg_object_string(obj));
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(LIC2, package_id,
			    pkg_object_string(obj));
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(LIC2));
			return (EPKG_FATAL);
		}
	}
	option = NULL;
	while (pkg_options(pkg, &option) == EPKG_OK) {
		ret = pkg_repo_binary_run_prstatement(OPT1, pkg_option_opt(option));
		if (ret == SQLITE_DONE)
		    ret = pkg_repo_binary_run_prstatement(OPT2, pkg_option_opt(option),
				pkg_option_value(option), package_id);
		if(ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(OPT2));
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD));
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(annotations, &it))) {
		const char *note_tag = pkg_object_key(obj);
		const char *note_val = pkg_object_string(obj);

		ret = pkg_repo_binary_run_prstatement(ANNOTATE1, note_tag);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(ANNOTATE1, note_val);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(ANNOTATE2, package_id,
				  note_tag, note_val);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(ANNOTATE2));
			return (EPKG_FATAL);
		}
	}

	return (EPKG_OK);
}
Example #8
0
static void
pipeevent(struct pkg_event *ev)
{
	int i;
	struct pkg_dep *dep = NULL;
	struct sbuf *msg, *buf;
	const char *message;
	struct pkg_event_conflict *cur_conflict;
	if (eventpipe < 0)
		return;

	msg = sbuf_new_auto();
	buf = sbuf_new_auto();

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {"
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d}}",
		    sbuf_json_escape(buf, ev->e_errno.func),
		    sbuf_json_escape(buf, ev->e_errno.arg),
		    sbuf_json_escape(buf, strerror(ev->e_errno.no)),
		    ev->e_errno.no);
		break;
	case PKG_EVENT_ERROR:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"%s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_NOTICE:
		sbuf_printf(msg, "{ \"type\": \"NOTICE\", "
		    "\"data\": {\"msg\": \"%s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_notice.msg));
		break;
	case PKG_EVENT_DEVELOPER_MODE:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_UPDATE_ADD:
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
		    "}}",
		    ev->e_upd_add.done,
		    ev->e_upd_add.total
		    );
		break;
	case PKG_EVENT_UPDATE_REMOVE:
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
		    "}}",
		    ev->e_upd_remove.done,
		    ev->e_upd_remove.total
		    );
		break;
	case PKG_EVENT_FETCH_BEGIN:
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
		    sbuf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_FETCH_FINISHED:
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
		    sbuf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		pkg_get(ev->e_install_finished.pkg,
		    PKG_MESSAGE, &message);

		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"message\": \"%S\""
		    "}}",
		    ev->e_install_finished.pkg,
		    ev->e_install_finished.pkg,
		    sbuf_json_escape(buf, message));
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
		    "\"data\": {}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
			"\"data\": { "
			"\"pkguid\": \"%s\", "
			"\"pkgpath\": \"%s\", "
			"\"conflicts\": [",
			ev->e_integrity_conflict.pkg_uid,
			ev->e_integrity_conflict.pkg_path);
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict != NULL) {
			if (cur_conflict->next != NULL) {
				sbuf_printf(msg, "{\"uid\":\"%s\"},",
						cur_conflict->uid);
			}
			else {
				sbuf_printf(msg, "{\"uid\":\"%s\"}",
						cur_conflict->uid);
				break;
			}
			cur_conflict = cur_conflict->next;
		}
		sbuf_cat(msg, "]}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
		    "\"data\": {\"conflicting\": %d}}",
		    ev->e_integrity_finished.conflicting);
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_deinstall_begin.pkg,
		    ev->e_deinstall_begin.pkg);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_deinstall_finished.pkg,
		    ev->e_deinstall_finished.pkg);
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
		    "\"pkgnewversion\": \"%v\""
		    "}}",
		    ev->e_upgrade_begin.old,
		    ev->e_upgrade_begin.old,
		    ev->e_upgrade_begin.new);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
		    "\"pkgnewversion\": \"%v\""
		    "}}",
		    ev->e_upgrade_begin.old,
		    ev->e_upgrade_begin.old,
		    ev->e_upgrade_begin.new);
		break;
	case PKG_EVENT_LOCKED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%n\""
		    "}}",
		    ev->e_locked.pkg,
		    ev->e_locked.pkg);
		break;
	case PKG_EVENT_REQUIRED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"force\": %S, "
		    "\"required_by\": [",
		    ev->e_required.pkg,
		    ev->e_required.pkg,
		    ev->e_required.force == 1 ? "true": "false");
		while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK)
			sbuf_printf(msg, "{ \"pkgname\": \"%s\", "
			    "\"pkgversion\": \"%s\" }, ",
			    pkg_dep_name(dep),
			    pkg_dep_version(dep));
		sbuf_setpos(msg, sbuf_len(msg) - 2);
		sbuf_cat(msg, "]}}");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_already_installed.pkg,
		    ev->e_already_installed.pkg);
		break;
	case PKG_EVENT_MISSING_DEP:
		sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
		    "\"data\": { "
		    "\"depname\": \"%s\", "
		    "\"depversion\": \"%s\""
		    "}}" ,
		    pkg_dep_name(ev->e_missing_dep.dep),
		    pkg_dep_version(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}" ,
		    ev->e_remotedb.repo);
		break;
	case PKG_EVENT_NOLOCALDB:
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"path\": \"%S\""
		    "}}",
		    ev->e_file_mismatch.pkg,
		    ev->e_file_mismatch.pkg,
		    sbuf_json_escape(buf, pkg_file_path(ev->e_file_mismatch.file)));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d"
		    "}}",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_errno.func),
		    sbuf_json_escape(buf, ev->e_plugin_errno.arg),
		    sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
		    ev->e_plugin_errno.no);
		break;
	case PKG_EVENT_PLUGIN_ERROR:
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_error.msg));
		break;
	case PKG_EVENT_PLUGIN_INFO:
		sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_info.msg));
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
		sbuf_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
		    "\"data\": {"
		        "\"name\": \"%s\", "
			"\"updated\": %d, "
			"\"removed\": %d, "
			"\"added\": %d, "
			"\"processed\": %d"
			"}}", ev->e_incremental_update.reponame,
			ev->e_incremental_update.updated,
			ev->e_incremental_update.removed,
			ev->e_incremental_update.added,
			ev->e_incremental_update.processed);
		break;
	case PKG_EVENT_QUERY_YESNO:
		sbuf_printf(msg, "{ \"type\": \"QUERY_YESNO\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"default\": \"%d\""
			"}}", ev->e_query_yesno.msg,
			ev->e_query_yesno.deft);
		break;
	case PKG_EVENT_QUERY_SELECT:
		sbuf_printf(msg, "{ \"type\": \"QUERY_SELECT\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"ncnt\": \"%d\","
			"\"default\": \"%d\","
			"\"items\": ["
			, ev->e_query_select.msg,
			ev->e_query_select.ncnt,
			ev->e_query_select.deft);
		for (i = 0; i < ev->e_query_select.ncnt - 1; i++)
		{
			sbuf_printf(msg, "{ \"text\": \"%s\" },",
				ev->e_query_select.items[i]);
		}
		sbuf_printf(msg, "{ \"text\": \"%s\" } ] }}",
			ev->e_query_select.items[i]);
		break;
	case PKG_EVENT_PROGRESS_START:
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", "
		  "\"data\": {}}");
		break;
	case PKG_EVENT_PROGRESS_TICK:
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", "
		  "\"data\": { \"current\": %ld, \"total\" : %ld}}",
		  ev->e_progress_tick.current, ev->e_progress_tick.total);
		break;
	case PKG_EVENT_BACKUP:
	case PKG_EVENT_RESTORE:
		break;
	default:
		break;
	}
	sbuf_finish(msg);
	dprintf(eventpipe, "%s\n", sbuf_data(msg));
	sbuf_delete(msg);
	sbuf_delete(buf);
}
Example #9
0
File: event.c Project: dotike/pkg
int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL, *pkg_new, *pkg_old;
	int *debug = data;
	struct pkg_event_conflict *cur_conflict;
	const char *filename;

	if (msg_buf == NULL) {
		msg_buf = sbuf_new_auto();
	}

	/*
	 * If a progressbar has been interrupted by another event, then
	 * we need to add a newline to prevent bad formatting.
	 */
	if (progress_started && ev->type != PKG_EVENT_PROGRESS_TICK &&
	    !progress_interrupted) {
		putchar('\n');
		progress_interrupted = true;
	}

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg,
		    strerror(ev->e_errno.no));
		break;
	case PKG_EVENT_ERROR:
		warnx("%s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_NOTICE:
		if (!quiet)
			printf("%s\n", ev->e_pkg_notice.msg);
		break;
	case PKG_EVENT_DEVELOPER_MODE:
		warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_UPDATE_ADD:
		if (quiet || !isatty(STDOUT_FILENO))
			break;
		printf("\rPushing new entries %d/%d", ev->e_upd_add.done, ev->e_upd_add.total);
		if (ev->e_upd_add.total == ev->e_upd_add.done)
			printf("\n");
		break;
	case PKG_EVENT_UPDATE_REMOVE:
		if (quiet || !isatty(STDOUT_FILENO))
			break;
		printf("\rRemoving entries %d/%d", ev->e_upd_remove.done, ev->e_upd_remove.total);
		if (ev->e_upd_remove.total == ev->e_upd_remove.done)
			printf("\n");
		break;
	case PKG_EVENT_FETCH_BEGIN:
		if (quiet)
			break;
		filename = strrchr(ev->e_fetching.url, '/');
		if (filename != NULL) {
			filename++;
		} else {
			/*
			 * We failed at being smart, so display
			 * the entire url.
			 */
			filename = ev->e_fetching.url;
		}
		job_status_begin(msg_buf);
		progress_debit = true;
		sbuf_printf(msg_buf, "Fetching %s", filename);

		break;
	case PKG_EVENT_FETCH_FINISHED:
		progress_debit = false;
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		if (quiet)
			break;
		else {
			nbdone++;
			job_status_begin(msg_buf);

			pkg = ev->e_install_begin.pkg;
			pkg_sbuf_printf(msg_buf, "Installing %n-%v...\n", pkg,
			    pkg);
			sbuf_finish(msg_buf);
			printf("%s", sbuf_data(msg_buf));
		}
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
			break;
		pkg = ev->e_install_finished.pkg;
		if (pkg_has_message(pkg)) {
			if (messages == NULL)
				messages = sbuf_new_auto();
			pkg_sbuf_printf(messages, "Message for %n-%v:\n%M\n",
			    pkg, pkg, pkg);
		}
		break;
	case PKG_EVENT_EXTRACT_BEGIN:
		if (quiet)
			break;
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
			pkg_sbuf_printf(msg_buf, "Extracting %n-%v", pkg, pkg);
		}
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
		break;
	case PKG_EVENT_ADD_DEPS_BEGIN:
		++add_deps_depth;
		break;
	case PKG_EVENT_ADD_DEPS_FINISHED:
		--add_deps_depth;
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		if (quiet)
			break;
		printf("Checking integrity...");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		if (quiet)
			break;
		printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting);
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
		if (*debug == 0)
			break;
		printf("\nConflict found on path %s between %s and ",
		    ev->e_integrity_conflict.pkg_path,
		    ev->e_integrity_conflict.pkg_uid);
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict) {
			if (cur_conflict->next)
				printf("%s, ", cur_conflict->uid);
			else
				printf("%s", cur_conflict->uid);

			cur_conflict = cur_conflict->next;
		}
		printf("\n");
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		if (quiet)
			break;
		nbdone++;

		job_status_begin(msg_buf);

		pkg = ev->e_install_begin.pkg;
		pkg_sbuf_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg);
		sbuf_finish(msg_buf);
		printf("%s", sbuf_data(msg_buf));
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
			break;
		break;
	case PKG_EVENT_DELETE_FILES_BEGIN:
		if (quiet)
			break;
		else {
			job_status_begin(msg_buf);
			pkg = ev->e_install_begin.pkg;
			pkg_sbuf_printf(msg_buf, "Deleting files for %n-%v",
			    pkg, pkg);
		}
		break;
	case PKG_EVENT_DELETE_FILES_FINISHED:
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		if (quiet)
			break;
		pkg_new = ev->e_upgrade_begin.n;
		pkg_old = ev->e_upgrade_begin.o;
		nbdone++;

		job_status_begin(msg_buf);

		switch (pkg_version_change_between(pkg_new, pkg_old)) {
		case PKG_DOWNGRADE:
			pkg_sbuf_printf(msg_buf, "Downgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		case PKG_REINSTALL:
			pkg_sbuf_printf(msg_buf, "Reinstalling %n-%v...\n",
		    pkg_old, pkg_old);
			break;
		case PKG_UPGRADE:
			pkg_sbuf_printf(msg_buf, "Upgrading %n from %v to %v...\n",
			    pkg_new, pkg_old, pkg_new);
			break;
		}
		sbuf_finish(msg_buf);
		printf("%s", sbuf_data(msg_buf));
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
			break;
		pkg_new = ev->e_upgrade_finished.n;
		if (pkg_has_message(pkg_new)) {
			if (messages == NULL)
				messages = sbuf_new_auto();
			pkg_sbuf_printf(messages, "Message for %n-%v:\n %M\n",
				pkg_new, pkg_new, pkg_new);
		}
		break;
	case PKG_EVENT_LOCKED:
		pkg = ev->e_locked.pkg;
		pkg_printf("\n%n-%v is locked and may not be modified\n", pkg, pkg);
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		pkg_printf("\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg);
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		if (quiet)
			break;
		pkg = ev->e_already_installed.pkg;
		pkg_printf("the most recent version of %n-%v is already installed\n",
				pkg, pkg);
		break;
	case PKG_EVENT_NOT_FOUND:
		printf("Package '%s' was not found in "
		    "the repositories\n", ev->e_not_found.pkg_name);
		break;
	case PKG_EVENT_MISSING_DEP:
		warnx("Missing dependency '%s-%s'",
		    pkg_dep_name(ev->e_missing_dep.dep),
		    pkg_dep_version(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		fprintf(stderr, "Unable to open remote database \"%s\". "
		    "Try running '%s update' first.\n", ev->e_remotedb.repo,
		    getprogname());
		break;
	case PKG_EVENT_NOLOCALDB:
		fprintf(stderr, "Local package database nonexistent!\n");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		newpkgversion = true;
		printf("New version of pkg detected; it needs to be "
		    "installed first.\n");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg = ev->e_file_mismatch.pkg;
		pkg_fprintf(stderr, "%n-%v: checksum mismatch for %Fn\n", pkg,
		    pkg, ev->e_file_mismatch.file);
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
		warnx("%s: %s(%s): %s",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_errno.func, ev->e_plugin_errno.arg,
		    strerror(ev->e_plugin_errno.no));
		break;
	case PKG_EVENT_PLUGIN_ERROR:
		warnx("%s: %s",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_error.msg);
		break;
	case PKG_EVENT_PLUGIN_INFO:
		if (quiet)
			break;
		printf("%s: %s\n",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_info.msg);
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
		if (!quiet)
			printf("%s repository update completed. %d packages processed.\n",
			    ev->e_incremental_update.reponame,
			    ev->e_incremental_update.processed);
		break;
	case PKG_EVENT_DEBUG:
		fprintf(stderr, "DBG(%d)[%d]> %s\n", ev->e_debug.level,
			(int)getpid(), ev->e_debug.msg);
		break;
	case PKG_EVENT_QUERY_YESNO:
		return ( ev->e_query_yesno.deft ?
			query_yesno(true, ev->e_query_yesno.msg, "[Y/n]") :
			query_yesno(false, ev->e_query_yesno.msg, "[y/N]") );
		break;
	case PKG_EVENT_QUERY_SELECT:
		return query_select(ev->e_query_select.msg, ev->e_query_select.items,
			ev->e_query_select.ncnt, ev->e_query_select.deft);
		break;
	case PKG_EVENT_SANDBOX_CALL:
		return ( event_sandboxed_call(ev->e_sandbox_call.call,
				ev->e_sandbox_call.fd,
				ev->e_sandbox_call.userdata) );
		break;
	case PKG_EVENT_SANDBOX_GET_STRING:
		return ( event_sandboxed_get_string(ev->e_sandbox_call_str.call,
				ev->e_sandbox_call_str.result,
				ev->e_sandbox_call_str.len,
				ev->e_sandbox_call_str.userdata) );
		break;
	case PKG_EVENT_PROGRESS_START:
		progressbar_start(ev->e_progress_start.msg);
		break;
	case PKG_EVENT_PROGRESS_TICK:
		progressbar_tick(ev->e_progress_tick.current,
		    ev->e_progress_tick.total);
		break;
	case PKG_EVENT_BACKUP:
		sbuf_cat(msg_buf, "Backing up");
		sbuf_finish(msg_buf);
		break;
	case PKG_EVENT_RESTORE:
		sbuf_cat(msg_buf, "Restoring");
		sbuf_finish(msg_buf);
		break;
	default:
		break;
	}

	return 0;
}
Example #10
0
File: event.c Project: afb/pkgng
int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	const char *message;
	int *debug = data;
	(void) debug;
	const char *name, *version, *newversion;
	const char *filename;
	struct pkg_event_conflict *cur_conflict;

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg,
		    strerror(ev->e_errno.no));
		break;
	case PKG_EVENT_ERROR:
		warnx("%s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_NOTICE:
		if (!quiet)
			warnx("%s", ev->e_pkg_notice.msg);
		break;
	case PKG_EVENT_DEVELOPER_MODE:
		warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_FETCHING:
		if (quiet || !isatty(fileno(stdin)))
			break;
		if (fetched == 0) {
			filename = strrchr(ev->e_fetching.url, '/');
			if (filename != NULL) {
				filename++;
			} else {
				/*
				 * We failed at being smart, so display
				 * the entire url.
				 */
				filename = ev->e_fetching.url;
			}
			strlcpy(url, filename, sizeof(url));
			start_progress_meter(url, ev->e_fetching.total,
			    &fetched);
		}
		fetched = ev->e_fetching.done;
		if (ev->e_fetching.done == ev->e_fetching.total) {
			stop_progress_meter();
			fetched = 0;
		}
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		nbdone++;
		if (nbactions > 0)
			printf("[%d/%d] ", nbdone, nbactions);
		printf("Installing %s-%s...", name, version);
		/* print to the terminal title*/
		printf("%c]0;[%d/%d] Installing %s-%s%c", '\033', nbdone, nbactions, name, version, '\007');

		break;
	case PKG_EVENT_INSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message);
		if (message != NULL && message[0] != '\0') {
			if (messages == NULL)
				messages = sbuf_new_auto();
			sbuf_printf(messages, "%s\n", message);
		}
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		if (quiet)
			break;
		printf("Checking integrity...");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
		printf("\nConflict found on path %s between %s-%s(%s) and ",
			ev->e_integrity_conflict.pkg_path,
			ev->e_integrity_conflict.pkg_name,
			ev->e_integrity_conflict.pkg_version,
			ev->e_integrity_conflict.pkg_origin);
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict) {
			if (cur_conflict->next)
				printf("%s-%s(%s), ", cur_conflict->name, cur_conflict->version, cur_conflict->origin);
			else
				printf("%s-%s(%s)", cur_conflict->name, cur_conflict->version, cur_conflict->origin);

			cur_conflict = cur_conflict->next;
		}
		printf("\n");
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		nbdone++;
		if (nbactions > 0)
			printf("[%d/%d] ", nbdone, nbactions);
		printf("Deleting %s-%s...", name, version);
		printf("%c]0;[%d/%d] Deleting %s-%s%c", '\033', nbdone,
		    nbactions, name, version, '\007');
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		if (quiet)
			break;
		pkg_get(ev->e_upgrade_begin.pkg, PKG_NAME, &name,
		    PKG_VERSION, &newversion, PKG_OLD_VERSION, &version);
		nbdone++;
		if (nbactions > 0)
			printf("[%d/%d] ", nbdone, nbactions);
		switch (pkg_version_cmp(version, newversion)) {
		case 1:
			printf("Downgrading %s from %s to %s...",
			    name, version, newversion);
			printf("%c]0;[%d/%d] Downgrading %s from %s to %s%c",
			    '\033', nbdone, nbactions, name, version,
			    newversion, '\007');
			break;
		case 0:
			printf("Reinstalling %s-%s",
			    name, version);
			printf("%c]0;[%d/%d] Reinstalling %s-%s%c", '\033',
			    nbdone, nbactions, name, version, '\007');
			break;
		case -1:
			printf("Upgrading %s from %s to %s...",
			    name, version, newversion);
			printf("%c]0;[%d/%d] Upgrading %s from %s to %s%c",
			    '\033', nbdone, nbactions, name, version,
			    newversion, '\007');
			break;
		}
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		if (quiet)
			break;
		printf(" done\n");
		break;
	case PKG_EVENT_LOCKED:
		pkg = ev->e_locked.pkg;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		fprintf(stderr, "\n%s-%s is locked and may not be modified\n",
			name, version);
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		fprintf(stderr, "\n%s-%s is required by:", name, version);
		while (pkg_rdeps(pkg, &dep) == EPKG_OK)
			fprintf(stderr, " %s-%s", pkg_dep_name(dep),
			    pkg_dep_version(dep));
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		if (quiet)
			break;
		pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		printf("%s-%s already installed\n", name, version);
		break;
	case PKG_EVENT_NOT_FOUND:
		printf("Package '%s' was not found in "
		    "the repositories\n", ev->e_not_found.pkg_name);
		break;
	case PKG_EVENT_MISSING_DEP:
		fprintf(stderr, "missing dependency %s-%s\n",
		    pkg_dep_name(ev->e_missing_dep.dep),
		    pkg_dep_version(ev->e_missing_dep.dep));
		break;
	case PKG_EVENT_NOREMOTEDB:
		fprintf(stderr, "Unable to open remote database \"%s\". "
		    "Try running '%s update' first.\n", ev->e_remotedb.repo,
		    getprogname());
		break;
	case PKG_EVENT_NOLOCALDB:
		fprintf(stderr, "Local package database nonexistent!\n");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		printf("New version of pkg detected; it needs to be "
		    "installed first.\nAfter this upgrade it is recommended "
		    "that you do a full upgrade using: 'pkg upgrade'\n\n");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name,
		    PKG_VERSION, &version);
		fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name,
		    version, pkg_file_path(ev->e_file_mismatch.file));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
		warnx("%s: %s(%s): %s", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
		    ev->e_plugin_errno.func, ev->e_plugin_errno.arg, strerror(ev->e_plugin_errno.no));
		break;
	case PKG_EVENT_PLUGIN_ERROR:
		warnx("%s: %s", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), ev->e_plugin_error.msg);
		break;
	case PKG_EVENT_PLUGIN_INFO:
		if (quiet)
			break;
		printf("%s: %s\n", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), ev->e_plugin_info.msg);
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
		if (!quiet)
			printf("Incremental update completed, %d packages processed:\n"
					"%d packages updated, %d removed and %d added.\n",
					ev->e_incremental_update.processed,
					ev->e_incremental_update.updated,
					ev->e_incremental_update.removed,
					ev->e_incremental_update.added);
		break;
	default:
		break;
	}

	return 0;
}
Example #11
0
int
pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_key *keys)
{
	const char	*arch;
	const char	*origin;
	const char	*name;
	struct archive	*a;
	struct archive_entry *ae;
	struct pkg	*pkg = NULL;
	struct pkg_dep	*dep = NULL;
	struct pkg      *pkg_inst = NULL;
	bool		 extract = true;
	bool		 handle_rc = false;
	bool		 disable_mtree;
	char		 dpath[MAXPATHLEN];
	const char	*basedir;
	const char	*ext;
	char		*mtree;
	char		*prefix;
	int		 retcode = EPKG_OK;
	int		 ret;

	assert(path != NULL);

	/*
	 * Open the package archive file, read all the meta files and set the
	 * current archive_entry to the first non-meta file.
	 * If there is no non-meta files, EPKG_END is returned.
	 */
	ret = pkg_open2(&pkg, &a, &ae, path, keys, 0);
	if (ret == EPKG_END)
		extract = false;
	else if (ret != EPKG_OK) {
		retcode = ret;
		goto cleanup;
	}
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_begin(pkg);

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	if (flags & PKG_ADD_AUTOMATIC)
		pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true);

	/*
	 * Check the architecture
	 */

	pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin, PKG_NAME, &name);

	if (!is_valid_abi(arch, true)) {
		if ((flags & PKG_ADD_FORCE) == 0) {
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	}

	/*
	 * Check if the package is already installed
	 */

	ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC);
	if (ret == EPKG_OK) {
		if ((flags & PKG_FLAG_FORCE) == 0) {
			pkg_emit_already_installed(pkg_inst);
			retcode = EPKG_INSTALLED;
			pkg_free(pkg_inst);
			pkg_inst = NULL;
			goto cleanup;
		}
		else {
			pkg_emit_notice("package %s is already installed, forced install", name);
			pkg_free(pkg_inst);
			pkg_inst = NULL;
		}
	} else if (ret != EPKG_END) {
		retcode = ret;
		goto cleanup;
	}

	/*
	 * Check for dependencies by searching the same directory as
	 * the package archive we're reading.  Of course, if we're
	 * reading from a file descriptor or a unix domain socket or
	 * somesuch, there's no valid directory to search.
	 */

	if (pkg_type(pkg) == PKG_FILE) {
		basedir = dirname(path);
		if ((ext = strrchr(path, '.')) == NULL) {
			pkg_emit_error("%s has no extension", path);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	} else {
		basedir = NULL;
		ext = NULL;
	}

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (pkg_is_installed(db, pkg_dep_origin(dep)) == EPKG_OK)
			continue;

		if (basedir != NULL) {
			const char *dep_name = pkg_dep_name(dep);
			const char *dep_ver = pkg_dep_version(dep);

			snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
			    dep_name, dep_ver, ext);

			if ((flags & PKG_ADD_UPGRADE) == 0 &&
			    access(dpath, F_OK) == 0) {
				ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys);
				if (ret != EPKG_OK) {
					retcode = EPKG_FATAL;
					goto cleanup;
				}
			} else {
				pkg_emit_error("Missing dependency matching '%s'",
				    pkg_dep_get(dep, PKG_DEP_ORIGIN));
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		} else {
			retcode = EPKG_FATAL;
			pkg_emit_missing_dep(pkg, dep);
			goto cleanup;
		}
	}

	/* register the package before installing it in case there are
	 * problems that could be caught here. */
	retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_UPGRADE, flags & PKG_FLAG_FORCE);

	if (retcode != EPKG_OK)
		goto cleanup;

	/* MTREE replicates much of the standard functionality
	 * inplicit in the way pkg works.  It has to remain available
	 * in the ports for compatibility with the old pkg_tools, but
	 * ultimately, MTREE should be made redundant.  Use this for
	 * experimantal purposes and to develop MTREE-free versions of
	 * packages. */

	pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree);
	if (!disable_mtree) {
		pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
		if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
			goto cleanup_reg;
	}

	/*
	 * Execute pre-install scripts
	 */
	if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
		pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

	/* add the user and group if necessary */
	/* pkg_add_user_group(pkg); */

	/*
	 * Extract the files on disk.
	 */
	if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) {
		/* If the add failed, clean up (silently) */
		pkg_delete_files(pkg, 2);
		pkg_delete_dirs(db, pkg, 1);
		goto cleanup_reg;
	}

	/*
	 * Execute post install scripts
	 */
	if ((flags & PKG_ADD_NOSCRIPT) == 0) {
		if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS)
			pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
		else
			pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
	}

	/*
	 * start the different related services if the users do want that
	 * and that the service is running
	 */

	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
	if (handle_rc)
		pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

	cleanup_reg:
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkgdb_register_finale(db, retcode);

	if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_finished(pkg);

	cleanup:
	if (a != NULL) {
		archive_read_close(a);
		archive_read_free(a);
	}

	pkg_free(pkg);

	if (pkg_inst != NULL)
		pkg_free(pkg_inst);

	return (retcode);
}
Example #12
0
static void
pipeevent(struct pkg_event *ev)
{
    struct pkg *pkg = NULL;
    struct pkg_dep *dep = NULL;
    struct sbuf *msg, *buf;
    const char *message;
    const char *name, *version, *newversion;

    if (eventpipe < 0)
        return;

    msg = sbuf_new_auto();
    buf = sbuf_new_auto();

    switch(ev->type) {
    case PKG_EVENT_ERRNO:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {"
                    "\"msg\": \"%s(%s): %s\","
                    "\"errno\": %d}}",
                    sbuf_json_escape(buf, ev->e_errno.func),
                    sbuf_json_escape(buf, ev->e_errno.arg),
                    sbuf_json_escape(buf, strerror(ev->e_errno.no)),
                    ev->e_errno.no);
        break;
    case PKG_EVENT_ERROR:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {\"msg\": \"%s\"}}",
                    sbuf_json_escape(buf, ev->e_pkg_error.msg));
        break;
    case PKG_EVENT_DEVELOPER_MODE:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
                    sbuf_json_escape(buf, ev->e_pkg_error.msg));
        break;
    case PKG_EVENT_FETCHING:
        sbuf_printf(msg, "{ \"type\": \"INFO_FETCH\", "
                    "\"data\": { "
                    "\"url\": \"%s\", "
                    "\"fetched\": %" PRId64 ", "
                    "\"total\": %" PRId64
                    "}}",
                    sbuf_json_escape(buf, ev->e_fetching.url),
                    ev->e_fetching.done,
                    ev->e_fetching.total
                   );
        break;
    case PKG_EVENT_INSTALL_BEGIN:
        pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version
                   );
        break;
    case PKG_EVENT_INSTALL_FINISHED:
        pkg_get(ev->e_install_finished.pkg,
                PKG_MESSAGE, &message,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"message\": \"%s\""
                    "}}",
                    name,
                    version,
                    sbuf_json_escape(buf, message));
        break;
    case PKG_EVENT_INTEGRITYCHECK_BEGIN:
        sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
                    "\"data\": {}}");
        break;
    case PKG_EVENT_INTEGRITYCHECK_FINISHED:
        sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
                    "\"data\": {}}");
        break;
    case PKG_EVENT_DEINSTALL_BEGIN:
        pkg_get(ev->e_deinstall_begin.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_DEINSTALL_FINISHED:
        pkg_get(ev->e_deinstall_finished.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_UPGRADE_BEGIN:
        pkg_get(ev->e_upgrade_begin.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version,
                PKG_NEWVERSION, &newversion);

        sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\" ,"
                    "\"pkgnewversion\": \"%s\""
                    "}}",
                    name,
                    version,
                    newversion);
        break;
    case PKG_EVENT_UPGRADE_FINISHED:
        pkg_get(ev->e_upgrade_finished.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version,
                PKG_NEWVERSION, &newversion);

        sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\" ,"
                    "\"pkgnewversion\": \"%s\""
                    "}}",
                    name,
                    version,
                    newversion);
        break;
    case PKG_EVENT_LOCKED:
        pkg_get(ev->e_locked.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_REQUIRED:
        pkg_get(ev->e_required.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"force\": %s, "
                    "\"required_by\": [",
                    name,
                    version,
                    ev->e_required.force == 1 ? "true": "false");
        while (pkg_rdeps(pkg, &dep) == EPKG_OK)
            sbuf_printf(msg, "{ \"pkgname\": \"%s\", "
                        "\"pkgversion\": \"%s\" }, ",
                        pkg_dep_name(dep),
                        pkg_dep_version(dep));
        sbuf_setpos(msg, sbuf_len(msg) - 2);
        sbuf_cat(msg, "]}}");
        break;
    case PKG_EVENT_ALREADY_INSTALLED:
        pkg_get(ev->e_already_installed.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_MISSING_DEP:
        sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
                    "\"data\": { "
                    "\"depname\": \"%s\", "
                    "\"depversion\": \"%s\""
                    "}}" ,
                    pkg_dep_name(ev->e_missing_dep.dep),
                    pkg_dep_version(ev->e_missing_dep.dep));
        break;
    case PKG_EVENT_NOREMOTEDB:
        sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
                    "\"data\": { "
                    "\"url\": \"%s\" "
                    "}}" ,
                    ev->e_remotedb.repo);
        break;
    case PKG_EVENT_NOLOCALDB:
        sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
                    "\"data\": {} ");
        break;
    case PKG_EVENT_NEWPKGVERSION:
        sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
                    "\"data\": {} ");
        break;
    case PKG_EVENT_FILE_MISMATCH:
        pkg_get(ev->e_file_mismatch.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"path\": \"%s\""
                    "}}",
                    name,
                    version,
                    sbuf_json_escape(buf, pkg_file_path(ev->e_file_mismatch.file)));
        break;
    case PKG_EVENT_PLUGIN_ERRNO:
        sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s(%s): %s\","
                    "\"errno\": %d"
                    "}}",
                    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_errno.func),
                    sbuf_json_escape(buf, ev->e_plugin_errno.arg),
                    sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
                    ev->e_plugin_errno.no);
        break;
    case PKG_EVENT_PLUGIN_ERROR:
        sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s\""
                    "}}",
                    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_error.msg));
        break;
    case PKG_EVENT_PLUGIN_INFO:
        sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s\""
                    "}}",
                    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_info.msg));
        break;
    default:
        break;
    }
    sbuf_finish(msg);
    dprintf(eventpipe, "%s\n", sbuf_data(msg));
    sbuf_delete(msg);
    sbuf_delete(buf);
}
Example #13
0
int
pkgdb_repo_add_package(struct pkg *pkg, const char *pkg_path,
		sqlite3 *sqlite, const char *manifest_digest, bool forced)
{
	const char *name, *version, *origin, *comment, *desc;
	const char *arch, *maintainer, *www, *prefix, *sum, *rpath;
	int64_t			 flatsize, pkgsize;
	lic_t			 licenselogic;
	int			 ret;
	struct pkg_dep		*dep      = NULL;
	struct pkg_category	*category = NULL;
	struct pkg_license	*license  = NULL;
	struct pkg_option	*option   = NULL;
	struct pkg_shlib	*shlib    = NULL;
	struct pkg_note		*note     = NULL;
	int64_t			 package_id;

	pkg_get(pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
			    PKG_VERSION, &version, PKG_COMMENT, &comment,
			    PKG_DESC, &desc, PKG_ARCH, &arch,
			    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
			    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
			    PKG_LICENSE_LOGIC, &licenselogic, PKG_CKSUM, &sum,
			    PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &rpath);

try_again:
	if ((ret = run_prepared_statement(PKG, origin, name, version,
			comment, desc, arch, maintainer, www, prefix,
			pkgsize, flatsize, (int64_t)licenselogic, sum,
			rpath, manifest_digest)) != SQLITE_DONE) {
		if (ret == SQLITE_CONSTRAINT) {
			switch(maybe_delete_conflicting(origin,
					version, pkg_path, forced)) {
			case EPKG_FATAL: /* sqlite error */
				ERROR_SQLITE(sqlite);
				return (EPKG_FATAL);
				break;
			case EPKG_END: /* repo already has newer */
				return (EPKG_END);
				break;
			default: /* conflict cleared, try again */
				goto try_again;
				break;
			}
		} else {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}
	package_id = sqlite3_last_insert_rowid(sqlite);

	dep = NULL;
	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (run_prepared_statement(DEPS,
				pkg_dep_origin(dep),
				pkg_dep_name(dep),
				pkg_dep_version(dep),
				package_id) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	category = NULL;
	while (pkg_categories(pkg, &category) == EPKG_OK) {
		const char *cat_name = pkg_category_name(category);

		ret = run_prepared_statement(CAT1, cat_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(CAT2, package_id,
					cat_name);
		if (ret != SQLITE_DONE)
		{
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	license = NULL;
	while (pkg_licenses(pkg, &license) == EPKG_OK) {
		const char *lic_name = pkg_license_name(license);

		ret = run_prepared_statement(LIC1, lic_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(LIC2, package_id,
					lic_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}
	option = NULL;
	while (pkg_options(pkg, &option) == EPKG_OK) {
		ret = run_prepared_statement(OPT1, pkg_option_opt(option));
		if (ret == SQLITE_DONE)
		    ret = run_prepared_statement(OPT2, pkg_option_opt(option),
				pkg_option_value(option), package_id);
		if(ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = run_prepared_statement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(SHLIB_REQD, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = run_prepared_statement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(SHLIB_PROV, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	note = NULL;
	while (pkg_annotations(pkg, &note) == EPKG_OK) {
		const char *note_tag = pkg_annotation_tag(note);
		const char *note_val = pkg_annotation_value(note);

		ret = run_prepared_statement(ANNOTATE1, note_tag);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(ANNOTATE1, note_val);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(ANNOTATE2, package_id,
				  note_tag, note_val);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	return (EPKG_OK);
}
Example #14
0
int
pkg_add(struct pkgdb *db, const char *path, unsigned flags)
{
    const char	*arch;
    const char	*myarch;
    const char	*origin;
    struct archive	*a;
    struct archive_entry *ae;
    struct pkg	*pkg = NULL;
    struct pkg_dep	*dep = NULL;
    struct pkg      *pkg_inst = NULL;
    bool		 extract = true;
    bool		 handle_rc = false;
    char		 dpath[MAXPATHLEN + 1];
    const char	*basedir;
    const char	*ext;
    char		*mtree;
    char		*prefix;
    int		 retcode = EPKG_OK;
    int		 ret;

    assert(path != NULL);

    /*
     * Open the package archive file, read all the meta files and set the
     * current archive_entry to the first non-meta file.
     * If there is no non-meta files, EPKG_END is returned.
     */
    ret = pkg_open2(&pkg, &a, &ae, path);
    if (ret == EPKG_END)
        extract = false;
    else if (ret != EPKG_OK) {
        retcode = ret;
        goto cleanup;
    }
    if ((flags & PKG_ADD_UPGRADE) == 0)
        pkg_emit_install_begin(pkg);

    if (pkg_is_valid(pkg) != EPKG_OK) {
        pkg_emit_error("the package is not valid");
        return (EPKG_FATAL);
    }

    if (flags & PKG_ADD_AUTOMATIC)
        pkg_set(pkg, PKG_AUTOMATIC, true);

    /*
     * Check the architecture
     */

    pkg_config_string(PKG_CONFIG_ABI, &myarch);
    pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin);

    if (fnmatch(myarch, arch, FNM_CASEFOLD) == FNM_NOMATCH &&
            strncmp(arch, myarch, strlen(myarch)) != 0) {
        pkg_emit_error("wrong architecture: %s instead of %s",
                       arch, myarch);
        if ((flags & PKG_ADD_FORCE) == 0) {
            retcode = EPKG_FATAL;
            goto cleanup;
        }
    }

    /*
     * Check if the package is already installed
     */

    ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC);
    if (ret == EPKG_OK) {
        pkg_emit_already_installed(pkg_inst);
        retcode = EPKG_INSTALLED;
        goto cleanup;
    } else if (ret != EPKG_END) {
        retcode = ret;
        goto cleanup;
    }

    /*
     * Check for dependencies
     */

    basedir = dirname(path);
    if ((ext = strrchr(path, '.')) == NULL) {
        pkg_emit_error("%s has no extension", path);
        retcode = EPKG_FATAL;
        goto cleanup;
    }

    while (pkg_deps(pkg, &dep) == EPKG_OK) {
        if (pkg_is_installed(db, pkg_dep_origin(dep)) != EPKG_OK) {
            const char *dep_name = pkg_dep_name(dep);
            const char *dep_ver = pkg_dep_version(dep);

            snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
                     dep_name, dep_ver, ext);

            if ((flags & PKG_ADD_UPGRADE) == 0 &&
                    access(dpath, F_OK) == 0) {
                ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC);
                if (ret != EPKG_OK) {
                    retcode = EPKG_FATAL;
                    goto cleanup;
                }
            } else {
                retcode = EPKG_FATAL;
                pkg_emit_missing_dep(pkg, dep);
                goto cleanup;
            }
        }
    }

    /* register the package before installing it in case there are
     * problems that could be caught here. */
    if ((flags & PKG_ADD_UPGRADE) == 0)
        retcode = pkgdb_register_pkg(db, pkg, 0);
    else
        retcode = pkgdb_register_pkg(db, pkg, 1);

    if (retcode != EPKG_OK)
        goto cleanup;

    pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
    if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
        goto cleanup_reg;

    /*
     * Execute pre-install scripts
     */
    if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
        pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

    /* add the user and group if necessary */
    /* pkg_add_user_group(pkg); */

    /*
     * Extract the files on disk.
     */
    if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) {
        /* If the add failed, clean up */
        pkg_delete_files(pkg, 1);
        pkg_delete_dirs(db, pkg, 1);
        goto cleanup_reg;
    }

    /*
     * Execute post install scripts
     */
    if ((flags & PKG_ADD_NOSCRIPT) == 0) {
        if (flags & PKG_ADD_USE_UPGRADE_SCRIPTS)
            pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
        else
            pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
    }

    /*
     * start the different related services if the users do want that
     * and that the service is running
     */

    pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
    if (handle_rc)
        pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

cleanup_reg:
    if ((flags & PKG_ADD_UPGRADE) == 0)
        pkgdb_register_finale(db, retcode);

    if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0)
        pkg_emit_install_finished(pkg);

cleanup:
    if (a != NULL)
        archive_read_free(a);

    pkg_free(pkg);
    pkg_free(pkg_inst);

    return (retcode);
}
Example #15
0
int
pkg_create_repo(char *path, bool force,
    void (progress)(struct pkg *pkg, void *data), void *data)
{
	FTS *fts = NULL;
	struct thd_data thd_data;
	int num_workers;
	size_t len;
	pthread_t *tids = NULL;

	struct pkg_dep *dep = NULL;
	struct pkg_category *category = NULL;
	struct pkg_license *license = NULL;
	struct pkg_option *option = NULL;
	struct pkg_shlib *shlib = NULL;

	sqlite3 *sqlite = NULL;

	int64_t package_id;
	char *errmsg = NULL;
	int retcode = EPKG_OK;
	int ret;

	char *repopath[2];
	char repodb[MAXPATHLEN + 1];
	char repopack[MAXPATHLEN + 1];

	struct archive *a = NULL;
	struct archive_entry *ae = NULL;

	if (!is_dir(path)) {
		pkg_emit_error("%s is not a directory", path);
		return (EPKG_FATAL);
	}

	repopath[0] = path;
	repopath[1] = NULL;

	len = sizeof(num_workers);
	if (sysctlbyname("hw.ncpu", &num_workers, &len, NULL, 0) == -1)
		num_workers = 6;

	if ((fts = fts_open(repopath, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) {
		pkg_emit_errno("fts_open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	snprintf(repodb, sizeof(repodb), "%s/repo.sqlite", path);
	snprintf(repopack, sizeof(repopack), "%s/repo.txz", path);

	if (access(repopack, F_OK) == 0) {
		a = archive_read_new();
		archive_read_support_compression_all(a);
		archive_read_support_format_tar(a);
		ret = archive_read_open_filename(a, repopack, 4096);
		if (ret != ARCHIVE_OK) {
			/* if we can't unpack it it won't be useful for us */
			unlink(repopack);
		} else {
			while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
				if (!strcmp(archive_entry_pathname(ae),
				    "repo.sqlite")) {
					archive_entry_set_pathname(ae, repodb);
					archive_read_extract(a, ae,
					    EXTRACT_ARCHIVE_FLAGS);
					break;
				}
			}
		}
		if (a != NULL)
			archive_read_finish(a);
	}

	if ((retcode = initialize_repo(repodb, force, &sqlite)) != EPKG_OK)
		goto cleanup;

	if ((retcode = initialize_prepared_statements(sqlite)) != EPKG_OK)
		goto cleanup;

	thd_data.root_path = path;
	thd_data.max_results = num_workers;
	thd_data.num_results = 0;
	thd_data.stop = false;
	thd_data.fts = fts;
	pthread_mutex_init(&thd_data.fts_m, NULL);
	STAILQ_INIT(&thd_data.results);
	thd_data.thd_finished = 0;
	pthread_mutex_init(&thd_data.results_m, NULL);
	pthread_cond_init(&thd_data.has_result, NULL);
	pthread_cond_init(&thd_data.has_room, NULL);

	/* Launch workers */
	tids = calloc(num_workers, sizeof(pthread_t));
	for (int i = 0; i < num_workers; i++) {
		pthread_create(&tids[i], NULL, (void *)&read_pkg_file, &thd_data);
	}

	for (;;) {
		struct pkg_result *r;

		const char *name, *version, *origin, *comment, *desc;
		const char *arch, *maintainer, *www, *prefix;
		int64_t flatsize;
		lic_t licenselogic;

		pthread_mutex_lock(&thd_data.results_m);
		while ((r = STAILQ_FIRST(&thd_data.results)) == NULL) {
			if (thd_data.thd_finished == num_workers) {
				break;
			}
			pthread_cond_wait(&thd_data.has_result, &thd_data.results_m);
		}
		if (r != NULL) {
			STAILQ_REMOVE_HEAD(&thd_data.results, next);
			thd_data.num_results--;
			pthread_cond_signal(&thd_data.has_room);
		}
		pthread_mutex_unlock(&thd_data.results_m);
		if (r == NULL) {
			break;
		}

		if (r->retcode != EPKG_OK) {
			continue;
		}

		/* do not add if package if already in repodb
		   (possibly at a different pkg_path) */

		if (run_prepared_statement(EXISTS, r->cksum) != SQLITE_ROW) {
			ERROR_SQLITE(sqlite);
			goto cleanup;
		}
		if (sqlite3_column_int(STMT(EXISTS), 0) > 0) {
			continue;
		}

		if (progress != NULL)
			progress(r->pkg, data);

		pkg_get(r->pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
		    PKG_VERSION, &version, PKG_COMMENT, &comment,
		    PKG_DESC, &desc, PKG_ARCH, &arch,
		    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
		    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
		    PKG_LICENSE_LOGIC, &licenselogic);

	try_again:
		if ((ret = run_prepared_statement(PKG, origin, name, version,
		    comment, desc, arch, maintainer, www, prefix,
		    r->size, flatsize, (int64_t)licenselogic, r->cksum,
		    r->path)) != SQLITE_DONE) {
			if (ret == SQLITE_CONSTRAINT) {
				switch(maybe_delete_conflicting(origin,
				    version, r->path)) {
				case EPKG_FATAL: /* sqlite error */
					ERROR_SQLITE(sqlite);
					retcode = EPKG_FATAL;
					goto cleanup;
					break;
				case EPKG_END: /* repo already has newer */
					continue;
					break;
				default: /* conflict cleared, try again */
					goto try_again;
					break;
				}
			} else {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		package_id = sqlite3_last_insert_rowid(sqlite);

		dep = NULL;
		while (pkg_deps(r->pkg, &dep) == EPKG_OK) {
			if (run_prepared_statement(DEPS,
			    pkg_dep_origin(dep),
			    pkg_dep_name(dep),
			    pkg_dep_version(dep),
			    package_id) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		category = NULL;
		while (pkg_categories(r->pkg, &category) == EPKG_OK) {
			const char *cat_name = pkg_category_name(category);

			ret = run_prepared_statement(CAT1, cat_name);
			if (ret == SQLITE_DONE)
			    ret = run_prepared_statement(CAT2, package_id,
			        cat_name);
			if (ret != SQLITE_DONE)
			{
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		license = NULL;
		while (pkg_licenses(r->pkg, &license) == EPKG_OK) {
			const char *lic_name = pkg_license_name(license);

			ret = run_prepared_statement(LIC1, lic_name);
			if (ret == SQLITE_DONE)
				ret = run_prepared_statement(LIC2, package_id,
				    lic_name);
			if (ret != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}
		option = NULL;
		while (pkg_options(r->pkg, &option) == EPKG_OK) {
			if (run_prepared_statement(OPTS,
			    pkg_option_opt(option),
			    pkg_option_value(option),
			    package_id) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		shlib = NULL;
		while (pkg_shlibs(r->pkg, &shlib) == EPKG_OK) {
			const char *shlib_name = pkg_shlib_name(shlib);

			ret = run_prepared_statement(SHLIB1, shlib_name);
			if (ret == SQLITE_DONE)
			    ret = run_prepared_statement(SHLIB2, package_id,
			        shlib_name);
			if (ret != SQLITE_DONE)
			{
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		pkg_free(r->pkg);
		free(r);
	}

	if (pkgdb_transaction_commit(sqlite, NULL) != SQLITE_OK)
		retcode = EPKG_FATAL;

	cleanup:

	if (tids != NULL) {
		// Cancel running threads
		if (retcode != EPKG_OK) {
			pthread_mutex_lock(&thd_data.fts_m);
			thd_data.stop = true;
			pthread_mutex_unlock(&thd_data.fts_m);
		}
		// Join on threads to release thread IDs
		for (int i = 0; i < num_workers; i++) {
			pthread_join(tids[i], NULL);
		}
		free(tids);
	}

	if (fts != NULL)
		fts_close(fts);

	finalize_prepared_statements();

	if (sqlite != NULL)
		sqlite3_close(sqlite);

	if (errmsg != NULL)
		sqlite3_free(errmsg);

	sqlite3_shutdown();

	return (retcode);
}
Example #16
0
File: query.c Project: afb/pkgng
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
	char size[7];
	const char *tmp;
	bool tmp2;
	int64_t flatsize;
	int64_t timestamp;
	lic_t licenselogic;

	sbuf_clear(dest);

	while (qstr[0] != '\0') {
		if (qstr[0] == '%') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				pkg_get(pkg, PKG_NAME, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'v':
				pkg_get(pkg, PKG_VERSION, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'o':
				pkg_get(pkg, PKG_ORIGIN, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'R':
				pkg_get(pkg, PKG_REPONAME, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'p':
				pkg_get(pkg, PKG_PREFIX, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'm':
				pkg_get(pkg, PKG_MAINTAINER, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'c':
				pkg_get(pkg, PKG_COMMENT, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'w':
				pkg_get(pkg, PKG_WWW, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'i':
				pkg_get(pkg, PKG_INFOS, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'a':
				pkg_get(pkg, PKG_AUTOMATIC, &tmp2);
				sbuf_printf(dest, "%d", tmp2);
				break;
			case 'k':
				pkg_get(pkg, PKG_LOCKED, &tmp2);
				sbuf_printf(dest, "%d", tmp2);
				break;
			case 't':
				pkg_get(pkg, PKG_TIME, &timestamp);
				sbuf_printf(dest, "%" PRId64, timestamp);
				break;
			case 's':
				qstr++;
				pkg_get(pkg, PKG_FLATSIZE, &flatsize);
				if (qstr[0] == 'h') {
					humanize_number(size, sizeof(size),
					    flatsize, "B", HN_AUTOSCALE, 0);
					sbuf_cat(dest, size);
				} else if (qstr[0] == 'b') {
					sbuf_printf(dest, "%" PRId64, flatsize);
				}
				break;
			case 'e':
				pkg_get(pkg, PKG_DESC, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case '?':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS) > 0);
					break;
				case 'r':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS) > 0);
					break;
				case 'C':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES) > 0);
					break;
				case 'F':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES) > 0);
					break;
				case 'O':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS) > 0);
					break;
				case 'D':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS) > 0);
					break;
				case 'L':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES) > 0);
					break;
				case 'U':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS) > 0);
					break;
				case 'G':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS) > 0);
					break;
				case 'B':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0);
					break;
				case 'b':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0);
					break;
				case 'A':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS) > 0);
					break;
				}
				break;
			case '#':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS));
					break;
				case 'r':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS));
					break;
				case 'C':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES));
					break;
				case 'F':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES));
					break;
				case 'O':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS));
					break;
				case 'D':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS));
					break;
				case 'L':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES));
					break;
				case 'U':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS));
					break;
				case 'G':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS));
					break;
				case 'B':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED));
					break;
				case 'b':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED));
					break;
				case 'A':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS));
					break;
				}
				break;
			case 'l':
				pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic);
				switch (licenselogic) {
				case LICENSE_SINGLE:
					sbuf_cat(dest, "single");
					break;
				case LICENSE_OR:
					sbuf_cat(dest, "or");
					break;
				case LICENSE_AND:
					sbuf_cat(dest, "and");
					break;
				}
				break;
			case 'd':
				qstr++;
				if (qstr[0] == 'n')
					sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data));
				else if (qstr[0] == 'o')
					sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data));
				break;
			case 'r':
				qstr++;
				if (qstr[0] == 'n')
					sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data));
				else if (qstr[0] == 'o')
					sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data));
				break;
			case 'C':
				sbuf_cat(dest, pkg_category_name((struct pkg_category *)data));
				break;
			case 'F':
				qstr++;
				if (qstr[0] == 'p')
					sbuf_cat(dest, pkg_file_path((struct pkg_file *)data));
				else if (qstr[0] == 's')
					sbuf_cat(dest, pkg_file_cksum((struct pkg_file *)data));
				break;
			case 'O':
				qstr++;
				if (qstr[0] == 'k')
					sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_option_value((struct pkg_option *)data));
				break;
			case 'D':
				sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data));
				break;
			case 'L':
				sbuf_cat(dest, pkg_license_name((struct pkg_license *)data));
				break;
			case 'U':
				sbuf_cat(dest, pkg_user_name((struct pkg_user *)data));
				break;
			case 'G':
				sbuf_cat(dest, pkg_group_name((struct pkg_group *)data));
				break;
			case 'B':
			case 'b':
				sbuf_cat(dest, pkg_shlib_name((struct pkg_shlib *)data));
				break;
			case 'A':
				qstr++;
				if (qstr[0] == 't')
					sbuf_cat(dest, pkg_annotation_tag((struct pkg_note *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_annotation_value((struct pkg_note *)data));
				break;
			case 'M':
				pkg_get(pkg, PKG_MESSAGE, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case '%':
				sbuf_putc(dest, '%');
				break;
			}
		} else  if (qstr[0] == '\\') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				sbuf_putc(dest, '\n');
				break;
			case 'a':
				sbuf_putc(dest, '\a');
				break;
			case 'b':
				sbuf_putc(dest, '\b');
				break;
			case 'f':
				sbuf_putc(dest, '\f');
				break;
			case 'r':
				sbuf_putc(dest, '\r');
				break;
			case '\\':
				sbuf_putc(dest, '\\');
				break;
			case 't':
				sbuf_putc(dest, '\t');
				break;
			}
		} else {
			sbuf_putc(dest, qstr[0]);
		}
		qstr++;
	}
	sbuf_finish(dest);
}
Example #17
0
void
test_manifest(void)
{
	struct pkg *p = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_conflict *conflict = NULL;
	struct pkg_option *option = NULL;
	struct pkg_file *file = NULL;
	int i;

	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
	ATF_REQUIRE(p != NULL);
	ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest));

#if 0
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_NAME), "foobar") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "0.3") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_ORIGIN), "foo/bar") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_COMMENT), "A dummy manifest") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_ARCH), "amd64") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "800500") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_WWW), "http://www.foobar.com") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_MAINTAINER), "*****@*****.**") == 0);
#endif

	i = 0;
	while (pkg_deps(p, &dep) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
#if 0
	while (pkg_conflicts(p, &conflict) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);
#endif

	i = 0;
	while (pkg_options(p, &option) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") ==
				0);
#if 0
	ATF_REQUIRE(strcmp(pkg_file_sha256(file),
				"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
				== 0);
#endif
	pkg_free(p);
/*	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL);
	pkg_free(p);
*/
}
Example #18
0
int
pkg_old_emit_content(struct pkg *pkg, char **dest)
{
	struct sbuf *content = sbuf_new_auto();

	struct pkg_dep *dep = NULL;
	struct pkg_file *file = NULL;
	struct pkg_dir *dir = NULL;
	struct pkg_option *option = NULL;

	char option_type = 0;

	pkg_sbuf_printf(content,
	    "@comment PKG_FORMAT_REVISION:1.1\n"
	    "@name %n-%v\n"
	    "@comment ORIGIN:%o\n"
	    "@cwd %p\n"
	    /* hack because we can recreate the prefix split or origin */
	    "@cwd /\n", pkg, pkg, pkg, pkg);

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		sbuf_printf(content,
		    "@pkgdep %s-%s\n"
		    "@comment DEPORIGIN:%s\n",
		    pkg_dep_name(dep),
		    pkg_dep_version(dep),
		    pkg_dep_origin(dep));
	}

	while (pkg_files(pkg, &file) == EPKG_OK) {
		sbuf_printf(content,
		    "%s\n"
		    "@comment MD5:%s\n",
		     file->path + 1,
		     file->sum);
	}

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		sbuf_printf(content,
		    "@unexec /sbin/rmdir \"%s\" 2>/dev/null\n",
		    dir->path);
	}

	sbuf_printf(content, "@comment OPTIONS:");
	while (pkg_options(pkg, &option) == EPKG_OK) {
		/* Add space for previous option, if not the first. */
		if (option_type != 0)
			sbuf_cat(content, " ");

		if (strcmp(pkg_option_value(option), "on") == 0)
			option_type = '+';
		else
			option_type = '-';
		sbuf_printf(content, "%c%s",
		    option_type,
		    pkg_option_opt(option));
	}
	sbuf_printf(content, "\n");

	sbuf_finish(content);
	*dest = strdup(sbuf_get(content));
	sbuf_delete(content);

	return (EPKG_OK);
}
Example #19
0
void
test_manifest(void)
{
	struct pkg *p = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_conflict *conflict = NULL;
	struct pkg_option *option = NULL;
	struct pkg_category *category = NULL;
	struct pkg_file *file = NULL;
        struct pkg_manifest_key *keys = NULL;
	const char *pkg_str;
	int64_t pkg_int;
	int i;

	pkg_manifest_keys_new(&keys);
	ATF_REQUIRE(keys != NULL);

	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
	ATF_REQUIRE(p != NULL);
	ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest, strlen(manifest), keys));

	pkg_manifest_keys_free(keys);

	ATF_REQUIRE(pkg_get(p, PKG_NAME, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "foobar") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_VERSION, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "0.3") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_ORIGIN, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "foo/bar") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_COMMENT, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "A dummy manifest") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_ARCH, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "amd64") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_WWW, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "http://www.foobar.com") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_MAINTAINER, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "*****@*****.**") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_PREFIX, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "/opt/prefix") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_DESC, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "port description") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_MESSAGE, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "pkg message") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_FLATSIZE, &pkg_int) == EPKG_OK);
	ATF_REQUIRE(pkg_int == 10000);

	i = 0;
	while (pkg_deps(p, &dep) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
#if 0
	while (pkg_conflicts(p, &conflict) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);
#endif

	i = 0;
	while (pkg_options(p, &option) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
	while (pkg_categories(p, &category) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_category_name(category), "foo") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_category_name(category), "bar") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") ==
				0);
#if 0
	ATF_REQUIRE(strcmp(pkg_file_sha256(file),
				"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
				== 0);
#endif
	pkg_free(p);
/*	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL);
	pkg_free(p);
*/
}
Example #20
0
int
pkg_register_old(struct pkg *pkg)
{
	FILE *fp;
	char *content;
	const char *pkgdbdir, *tmp;
	char path[MAXPATHLEN];
	struct sbuf *install_script = sbuf_new_auto();
	struct sbuf *deinstall_script = sbuf_new_auto();
	struct pkg_dep *dep = NULL;

	pkg_to_old(pkg);
	pkg_old_emit_content(pkg, &content);

	pkgdbdir = pkg_object_string(pkg_config_get("PKG_DBDIR"));
	pkg_snprintf(path, sizeof(path), "%S/%n-%v", pkgdbdir, pkg, pkg);
	mkdir(path, 0755);

	pkg_snprintf(path, sizeof(path), "%S/%n-%v/+CONTENTS", pkgdbdir, pkg, pkg);
	fp = fopen(path, "w");
	fputs(content, fp);
	fclose(fp);

	pkg_snprintf(path, sizeof(path), "%S/%n-%v/+DESC", pkgdbdir, pkg, pkg);
	fp = fopen(path, "w");
	pkg_fprintf(fp, "%e", pkg);
	fclose(fp);

	pkg_snprintf(path, sizeof(path), "%s/%n-%v/+COMMENT", pkgdbdir, pkg, pkg);
	fp = fopen(path, "w");
	pkg_fprintf(fp, "%c\n", pkg);
	fclose(fp);

	if (pkg_has_message(pkg)) {
		pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DISPLAY", pkgdbdir, pkg, pkg);
		fp = fopen(path, "w");
		pkg_fprintf(fp, "%M", pkg);
		fclose(fp);
	}

	sbuf_clear(install_script);
	tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_printf(install_script,
		    "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_cat(install_script, tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_printf(install_script,
		    "if [ \"$2\" = \"POST-INSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}
	if (sbuf_len(install_script) > 0) {
		sbuf_finish(install_script);
		pkg_snprintf(path, sizeof(path), "%s/%n-%v/+INSTALL", pkgdbdir, pkg, pkg);
		fp = fopen(path, "w");
		fputs(sbuf_data(install_script), fp);
		fclose(fp);
	}

	sbuf_clear(deinstall_script);
	tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_printf(deinstall_script,
		    "if [ \"$2\" = \"DEINSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_cat(deinstall_script, tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL);
	if (tmp != NULL && tmp[0] != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_printf(deinstall_script,
		    "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}
	if (sbuf_len(deinstall_script) > 0) {
		sbuf_finish(deinstall_script);
		pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DEINSTALL", pkgdbdir, pkg, pkg);
		fp = fopen(path, "w");
		fputs(sbuf_data(deinstall_script), fp);
		fclose(fp);
	}

	while (pkg_deps(pkg, &dep)) {
		snprintf(path, sizeof(path), "%s/%s-%s/+REQUIRED_BY", pkgdbdir,
		    pkg_dep_name(dep), pkg_dep_version(dep));
		fp = fopen(path, "a");
		pkg_fprintf(fp, "%n-%v\n", pkg, pkg);
		fclose(fp);
	}

	return (EPKG_OK);
}
Example #21
0
int
event_callback(void *data, struct pkg_event *ev)
{
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	const char *message;
	int *debug = data;
	(void)debug;

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg);
		break;
	case PKG_EVENT_ERROR:
		warnx("%s", ev->e_pkg_error.msg);
		break;
	case PKG_EVENT_FETCHING:
		if (fetched == 0) {
			strlcpy(url, ev->e_fetching.url, sizeof(url));
			start_progress_meter(url, ev->e_fetching.total, &fetched);
		}
		fetched = ev->e_fetching.done;
		if (ev->e_fetching.done == ev->e_fetching.total) {
			stop_progress_meter();
			fetched = 0;
		}
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		printf("Installing %s-%s...",
			   pkg_get(ev->e_install_begin.pkg, PKG_NAME),
			   pkg_get(ev->e_install_begin.pkg, PKG_VERSION));
		fflush(stdout);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		printf(" done\n");
		message = pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE);
		if (message != NULL && message[0] != '\0')
			printf("%s\n", message);
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		printf("Deinstalling %s-%s...",
			   pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME),
			   pkg_get(ev->e_deinstall_begin.pkg, PKG_VERSION));
		fflush(stdout);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		printf(" done\n");
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		printf("Upgrading %s from %s to %s...",
				pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME),
				pkg_get(ev->e_upgrade_finished.pkg, PKG_VERSION),
				pkg_get(ev->e_upgrade_finished.pkg, PKG_NEWVERSION));
		fflush(stdout);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		printf("done\n");
		break;
	case PKG_EVENT_REQUIRED:
		pkg = ev->e_required.pkg;
		fprintf(stderr, "%s-%s is required by:", pkg_get(pkg, PKG_NAME),
				pkg_get(pkg, PKG_VERSION));
		while (pkg_rdeps(pkg, &dep) == EPKG_OK) {
			fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep));
		}
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		printf("%s-%s already installed\n",
				pkg_get(ev->e_already_installed.pkg, PKG_NAME),
				pkg_get(ev->e_already_installed.pkg, PKG_VERSION));
		break;
	default:
		break;
	}

	return 0;
}
Example #22
0
int
pkg_register_old(struct pkg *pkg)
{
	FILE *fp;
	char *name, *version, *content, *buf;
	const char *pkgdbdir, *tmp;
	char path[MAXPATHLEN];
	struct sbuf *install_script = sbuf_new_auto();
	struct sbuf *deinstall_script = sbuf_new_auto();
	struct pkg_dep *dep = NULL;

	pkg_to_old(pkg);
	pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
	pkg_old_emit_content(pkg, &content);

	pkg_config_string(PKG_CONFIG_DBDIR, &pkgdbdir);
	snprintf(path, sizeof(path), "%s/%s-%s", pkgdbdir, name, version);
	mkdir(path, 0755);

	snprintf(path, sizeof(path), "%s/%s-%s/+CONTENTS", pkgdbdir, name, version);
	fp = fopen(path, "w");
	fputs(content, fp);
	fclose(fp);

	pkg_get(pkg, PKG_DESC, &buf);
	snprintf(path, sizeof(path), "%s/%s-%s/+DESC", pkgdbdir, name, version);
	fp = fopen(path, "w");
	fputs(buf, fp);
	fclose(fp);

	pkg_get(pkg, PKG_COMMENT, &buf);
	snprintf(path, sizeof(path), "%s/%s-%s/+COMMENT", pkgdbdir, name, version);
	fp = fopen(path, "w");
	fprintf(fp, "%s\n", buf);
	fclose(fp);

	pkg_get(pkg, PKG_MESSAGE, &buf);
	if (buf != NULL && *buf != '\0') {
		snprintf(path, sizeof(path), "%s/%s-%s/+DISPLAY", pkgdbdir, name, version);
		fp = fopen(path, "w");
		fputs(buf, fp);
		fclose(fp);
	}

	sbuf_clear(install_script);
	tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_printf(install_script,
		    "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_cat(install_script, tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(install_script) == 0)
			sbuf_cat(install_script, "#!/bin/sh\n\n");
		sbuf_printf(install_script,
		    "if [ \"$2\" = \"POST-INSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}
	if (sbuf_len(install_script) > 0) {
		sbuf_finish(install_script);
		snprintf(path, sizeof(path), "%s/%s-%s/+INSTALL", pkgdbdir, name, version);
		fp = fopen(path, "w");
		fputs(sbuf_data(install_script), fp);
		fclose(fp);
	}

	sbuf_clear(deinstall_script);
	tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_printf(deinstall_script,
		    "if [ \"$2\" = \"DEINSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL);
	if (tmp != NULL && *tmp != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_cat(deinstall_script, tmp);
	}

	tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL);
	if (tmp != NULL && tmp[0] != '\0') {
		if (sbuf_len(deinstall_script) == 0)
			sbuf_cat(deinstall_script, "#!/bin/sh\n\n");
		sbuf_printf(deinstall_script,
		    "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n"
		    "%s\n"
		    "fi\n",
		    tmp);
	}
	if (sbuf_len(deinstall_script) > 0) {
		sbuf_finish(deinstall_script);
		snprintf(path, sizeof(path), "%s/%s-%s/+DEINSTALL", pkgdbdir, name, version);
		fp = fopen(path, "w");
		fputs(sbuf_data(deinstall_script), fp);
		fclose(fp);
	}

	while (pkg_deps(pkg, &dep)) {
		snprintf(path, sizeof(path), "%s/%s-%s/+REQUIRED_BY", pkgdbdir,
		    pkg_dep_name(dep), pkg_dep_version(dep));
		fp = fopen(path, "a");
		fprintf(fp, "%s-%s\n", name, version);
		fclose(fp);
	}

	return (EPKG_OK);
}