Example #1
0
File: check.c Project: baloo/pkgng
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_get(d, PKG_DEP_ORIGIN);

	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_get(d, PKG_DEP_NAME));
	e->version = strdup(pkg_dep_get(d, PKG_DEP_VERSION));
	e->origin = strdup(pkg_dep_get(d, PKG_DEP_ORIGIN));

	(*nbpkgs)++;

	STAILQ_INSERT_TAIL(dh, e, next);
}
/*
 * Converts a pkg_dep into a (partial) package ID.
 * 
 * The result may be NULL and should be freed using g_free.
 */
static gchar   *
dep_to_package_id(struct pkg_dep *dep)
{
	const char     *name;
	const char     *version;

	assert(dep != NULL);

	name = pkg_dep_get(dep, PKG_DEP_NAME);
	version = pkg_dep_get(dep, PKG_DEP_VERSION);

	return pk_package_id_build(name, version, "", "");
}
Example #3
0
File: audit.c Project: grembo/pkg
static void
print_recursive_rdeps(kh_pkgs_t *head, struct pkg *p, struct sbuf *sb,
    kh_pkgs_t *seen, bool top)
{
	struct pkg_dep *dep = NULL;
	int ret;
	khint_t k, h;

	while(pkg_rdeps(p, &dep) == EPKG_OK) {
		const char *name = pkg_dep_get(dep, PKG_DEP_NAME);

		k = kh_get_pkgs(seen, name);
		if (k == kh_end(seen)) {
			h = kh_get_pkgs(head, name);
			if (h != kh_end(head)) {
				kh_put_pkgs(seen, name, &ret);
				if (!top)
					sbuf_cat(sb, ", ");

				sbuf_cat(sb, name);

				print_recursive_rdeps(head, kh_val(head, h), sb, seen, false);

				top = false;
			}
		}
	}
}
Example #4
0
File: check.c Project: baloo/pkgng
static int
check_deps(struct pkgdb *db, struct pkg *p, struct deps_head *dh)
{
	struct pkg_dep *dep = NULL;
	char *name, *version, *origin;
	int nbpkgs = 0;

	assert(db != NULL);
	assert(p != NULL);

	name = version = origin = NULL;
	pkg_get(p, PKG_NAME, &name, PKG_VERSION, &version, PKG_ORIGIN, &origin);

	while (pkg_deps(p, &dep) == EPKG_OK) {
		/* do we have a missing dependency? */
		if (pkg_is_installed(db, pkg_dep_get(dep, PKG_DEP_ORIGIN)) != EPKG_OK) {
			printf("%s has a missing dependency: %s\n", origin,
			       pkg_dep_get(dep, PKG_DEP_ORIGIN)),
			add_missing_dep(dep, dh, &nbpkgs);
		}
	}
	
	return (nbpkgs);
}
Example #5
0
File: query.c Project: culot/pkgng
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
	char size[7];
	const char *tmp;
	bool automatic;
	int64_t flatsize;
	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);
					sbuf_cat(dest, tmp);
					break;
				case 'v':
					pkg_get(pkg, PKG_VERSION, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'o':
					pkg_get(pkg, PKG_ORIGIN, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'p':
					pkg_get(pkg, PKG_PREFIX, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'm':
					pkg_get(pkg, PKG_MAINTAINER, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'c':
					pkg_get(pkg, PKG_COMMENT, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'w':
					pkg_get(pkg, PKG_WWW, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'a':
					pkg_get(pkg, PKG_AUTOMATIC, &automatic);
					sbuf_printf(dest, "%d", automatic);
					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 '?':
					qstr++;
					switch (qstr[0]) {
						case 'd':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DEPS));
							break;
						case 'r':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_RDEPS));
							break;
						case 'C':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_CATEGORIES));
							break;
						case 'F':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_FILES));
							break;
						case 'O':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_OPTIONS));
							break;
						case 'D':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DIRS));
							break;
						case 'L':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_LICENSES));
							break;
						case 'U':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_USERS));
							break;
						case 'G':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_GROUPS));
							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_get((struct pkg_dep *)data, PKG_DEP_NAME));
					else if (qstr[0] == 'o')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN));
					else if (qstr[0] == 'v')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION));
					break;
				case 'r':
					qstr++;
					if (qstr[0] == 'n')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_NAME));
					else if (qstr[0] == 'o')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN));
					else if (qstr[0] == 'v')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION));
					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_get((struct pkg_file *)data, PKG_FILE_PATH));
					else if (qstr[0] == 's')
						sbuf_cat(dest, pkg_file_get((struct pkg_file *)data, PKG_FILE_SUM));
					break;
				case 'S':
					sbuf_cat(dest, pkg_script_data((struct pkg_script *)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 '%':
					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 #6
0
File: utils.c Project: culot/pkgng
int
print_info(struct pkg * const pkg, unsigned int opt)
{
	struct pkg_dep *dep = NULL;
	struct pkg_file *file = NULL;
	struct pkg_category *cat = NULL;
	struct pkg_license *lic = NULL;
	struct pkg_option *option = NULL;
	bool multirepos_enabled = false;
	char *m;
	char size[7];
	const char *name, *version, *prefix, *origin, *reponame, *repourl;
	const char *maintainer, *www, *comment, *desc;
	int64_t flatsize, newflatsize, newpkgsize;
	lic_t licenselogic;

	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);

	if (opt & INFO_RAW) {
		pkg_emit_manifest(pkg, &m);
		printf("%s\n", m);
		free(m);
	} else if (opt & INFO_FULL) {
		printf("%-15s: %s\n", "Name", name);
		printf("%-15s: %s\n", "Version", version);
		printf("%-15s: %s\n", "Origin", origin);
		printf("%-15s: %s\n", "Prefix", prefix);

		if ((pkg_type(pkg) == PKG_REMOTE) && multirepos_enabled)
			printf("%-15s: %s [%s]\n", "Repository", reponame, repourl);

                if (!pkg_list_is_empty(pkg, PKG_CATEGORIES)) {
                        printf("%-15s:", "Categories");
                        while (pkg_categories(pkg, &cat) == EPKG_OK)
                                printf(" %s", pkg_category_name(cat));
                        printf("\n");
                }

		if (!pkg_list_is_empty(pkg, PKG_LICENSES)) {
			printf("%-15s:", "Licenses");
			while (pkg_licenses(pkg, &lic) == EPKG_OK) {
				printf(" %s", pkg_license_name(lic));
				if (licenselogic != 1)
					printf(" %c", licenselogic);
				else
					printf(" ");
			}
			printf("\b \n");
		}

		printf("%-15s: %s\n", "Maintainer", maintainer);
		printf("%-15s: %s\n", "WWW", www);
		printf("%-15s: %s\n", "Comment", comment);

                if (!pkg_list_is_empty(pkg, PKG_OPTIONS)) {
                        printf("%-15s: \n", "Options");
                        while (pkg_options(pkg, &option) == EPKG_OK)
                                printf("\t%s: %s\n", pkg_option_opt(option), pkg_option_value(option));
                }

		if (pkg_type(pkg) == PKG_INSTALLED || pkg_type(pkg) == PKG_FILE) {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("%-15s: %s\n", "Flat size", size);
		} else {
			humanize_number(size, sizeof(size), newflatsize, "B", HN_AUTOSCALE, 0);
			printf("%-15s: %s\n", "Flat size", size);
			humanize_number(size, sizeof(size), newpkgsize, "B", HN_AUTOSCALE, 0);
			printf("%-15s: %s\n", "Pkg size", size);
		}

		printf("%-15s: \n%s\n", "Description", desc);
		printf("\n");
	} else if (opt & INFO_PRINT_DEP) {
		if (!(opt & INFO_QUIET))
			printf("%s-%s depends on:\n", name, version);

                while (pkg_deps(pkg, &dep) == EPKG_OK) {
                        printf("%s-%s\n", pkg_dep_get(dep, PKG_DEP_NAME), pkg_dep_get(dep, PKG_DEP_VERSION));
                }

                if (!(opt & INFO_QUIET))
                        printf("\n");
	} else if (opt & INFO_PRINT_RDEP) {
		if (!(opt & INFO_QUIET))
			printf("%s-%s is required by:\n", name, version);

                while (pkg_rdeps(pkg, &dep) == EPKG_OK) {
                        printf("%s-%s\n", pkg_dep_get(dep, PKG_DEP_NAME), pkg_dep_get(dep, PKG_DEP_VERSION));
                }

                if (!(opt & INFO_QUIET))
                        printf("\n");
	} else if (opt & INFO_LIST_FILES) {
		if (!(opt & INFO_QUIET))
			printf("%s-%s owns the following files:\n", name, version);

                while (pkg_files(pkg, &file) == EPKG_OK) {
                        printf("%s\n", pkg_file_get(file, PKG_FILE_PATH));
                }

                if (!(opt & INFO_QUIET))
                        printf("\n");
        } else if (opt & INFO_SIZE) {
		if (pkg_type(pkg) == PKG_INSTALLED) {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("%s-%s size is: %s\n", name, version, size);
		} else {
			humanize_number(size, sizeof(size), newflatsize, "B", HN_AUTOSCALE, 0);
			printf("%s-%s flat size is: %s\n", name, version, size);
			humanize_number(size, sizeof(size), newpkgsize, "B", HN_AUTOSCALE, 0);
			printf("%s-%s package size is: %s\n", name, version, size);
		}
        } else if (opt & INFO_ORIGIN) {
                if (opt & INFO_QUIET)
                        printf("%s\n", origin);
                else
                        printf("%s-%s: %s\n", name, version, origin);
        } else if (opt & INFO_PREFIX) {
                if (opt & INFO_QUIET)
                        printf("%s\n", prefix);
                else
                        printf("%s-%s: %s\n", name, version, prefix);
        } else {
                if (opt & INFO_QUIET)
                        printf("%s-%s\n", name, version);
                else {
			if ((pkg_type(pkg) == PKG_REMOTE) && multirepos_enabled)
				printf("%s-%s [repository: %s]: %s\n", name, version, reponame, comment);
			else
				printf("%s-%s: %s\n", name, version, comment);
		}
        }

        return (0);
}
Example #7
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 #8
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;
	const char *name, *version, *newversion;

	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:
		pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("Installing %s-%s...", name, version);
		fflush(stdout);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		printf(" done\n");
		pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message);
		if (message != NULL && message[0] != '\0')
			printf("%s\n", message);
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		printf("Checking integrity...");
		fflush(stdout);
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		printf(" done\n");
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("Deinstalling %s-%s...", name, version);
		fflush(stdout);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		printf(" done\n");
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version,
		    PKG_NEWVERSION, &newversion);
		printf("Upgrading %s from %s to %s...", name, version, newversion);
		fflush(stdout);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		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", pkg_dep_get(dep, PKG_DEP_ORIGIN));
		}
		if (ev->e_required.force == 1)
			fprintf(stderr, ", deleting anyway\n");
		else
			fprintf(stderr, "\n");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("%s-%s already installed\n", name, version);
		break;
	default:
		break;
	}

	return 0;
}