Пример #1
0
static int
fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs, bool yes)
{
	struct pkg_jobs *jobs = NULL;
	struct deps_entry *e = NULL;
	char **pkgs = NULL;
	int i = 0;
	pkg_flags f = PKG_FLAG_AUTOMATIC;

	assert(db != NULL);
	assert(nbpkgs > 0);

	if ((pkgs = calloc(nbpkgs, MAXPATHLEN + 1)) == NULL)
		err(1, "calloc()");

	STAILQ_FOREACH(e, dh, next)
		pkgs[i++] = e->origin;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) {
		free(pkgs);
		return (EPKG_ENODB);
	}

	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) {
		free(pkgs);
		return (EPKG_FATAL);
	}

	pkg_jobs_set_flags(jobs, f);

	if (pkg_jobs_add(jobs, MATCH_EXACT, pkgs, nbpkgs) == EPKG_FATAL) {
		pkg_jobs_free(jobs);
		return (EPKG_FATAL);
	}

	if (pkg_jobs_solve(jobs) != EPKG_OK) {
		pkg_jobs_free(jobs);
		return (EPKG_FATAL);
	}

	if (pkg_jobs_count(jobs) == 0) {
		printf("\nUnable to find packages for installation.\n\n");
		pkg_jobs_free(jobs);
		return (EPKG_FATAL);
	}

	/* print a summary before applying the jobs */
	print_jobs_summary(jobs, "The following packages will be installed:\n\n");
	
	if (yes == false)
		yes = query_yesno("\n>>> Try to fix the missing dependencies [y/N]: ");

	if (yes == true)
		pkg_jobs_apply(jobs);

	free(pkgs);
	pkg_jobs_free(jobs);

	return (EPKG_OK);
}
Пример #2
0
static Header ldhdr_bynevr(const struct pkg *pkg, void *foo) 
{
    struct pm_ctx    *pmctx;
    struct pkgdb     *db;
    struct pm_dbrec  dbrec;
    Header           h = NULL;
    
    DBGF("%s\n", pkg_snprintf_s(pkg));
    foo = foo;
    pmctx = pm_new("rpm");
    
    db = pkgdb_open(pmctx, "/", NULL, O_RDONLY, NULL);
    if (db == NULL) 
        goto l_end;
    
    if (pkgdb_get_package_hdr(db, pkg, &dbrec)) {
        n_assert(dbrec.hdr);
        h = pm_rpmhdr_link(dbrec.hdr);
    }
    
    pkgdb_free(db);
    
 l_end:
    pm_free(pmctx);
    return h;
}
Пример #3
0
static Header ldhdr_byrecno(const struct pkg *pkg, void *foo) 
{
    struct pm_ctx    *pmctx;
    struct pkgdb     *db;
    struct pkgdb_it  it;
    const struct pm_dbrec *dbrec;
    Header           h = NULL;

    foo = foo;
    n_assert(pkg->recno > 0);

    pmctx = pm_new("rpm");
    db = pkgdb_open(pmctx, "/", NULL, O_RDONLY, NULL);
    if (db == NULL) 
        goto l_end;
    
    pkgdb_it_init(db, &it, PMTAG_RECNO, (const char*)&pkg->recno);
    
    if ((dbrec = pkgdb_it_get(&it)) == NULL)
        goto l_end;

    // rpm's error: rpmdb_it_get_count(&it) with RECNO is always 0 
    if (dbrec->hdr)
        h = pm_rpmhdr_link(dbrec->hdr);
        
    pkgdb_it_destroy(&it);
    pkgdb_free(db);
    
 l_end:
    pm_free(pmctx);
    return h;
}
Пример #4
0
int
exec_backup(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	char		*backup_file = NULL;
	bool		 dump = false;
	bool		 restore = false;
	int		 ch;

	struct option longopts[] = {
		{ "dump",	required_argument,	NULL,	'd' },
		{ "restore",	required_argument,	NULL,	'r' },
		{ NULL,		0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+d:r:", longopts, NULL)) != -1) {
		switch (ch) {
		case 'd':
			dump = true;
			backup_file = optarg;
			break;
		case 'r':
			restore = true;
			backup_file = optarg;
			break;
		default:
			usage_backup();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if ( dump == restore ) {
		usage_backup();
		return (EX_USAGE);
	}

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

	if (dump) {
		if (isatty(fileno(stdout)))
				printf("Dumping database:\n");
		if (pkgdb_dump(db, backup_file) == EPKG_FATAL)
			return (EX_IOERR);
	}

	if (restore) {
		if (!quiet)
			printf("Restoring database:\n");
		if (pkgdb_load(db, backup_file) == EPKG_FATAL)
			return (EX_IOERR);
	}

	pkgdb_close(db);

	return (EX_OK);
}
Пример #5
0
static void
delete1pkg(const char *pkgdir)
{
	if (!pkgdb_open(ReadWrite))
		err(EXIT_FAILURE, "cannot open pkgdb");
	(void) pkgdb_remove_pkg(pkgdir);
	pkgdb_close();
}
Пример #6
0
static int
fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs, bool yes)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg_jobs *jobs = NULL;
	struct deps_entry *e = NULL;
	char **pkgs = NULL;
	int i = 0;

	assert(db != NULL);
	assert(nbpkgs > 0);

	if ((pkgs = calloc(nbpkgs, MAXPATHLEN + 1)) == NULL)
		err(1, "calloc()");

	STAILQ_FOREACH(e, dh, next)
		pkgs[i++] = e->origin;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		return (EPKG_ENODB);

	if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK)
		free(pkgs);

	if ((it = pkgdb_query_installs(db, MATCH_EXACT, nbpkgs, pkgs, NULL, false)) == NULL) {
		free(pkgs);
		pkg_jobs_free(jobs);
	}

	while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_DEPS) == EPKG_OK) {
		pkg_jobs_add(jobs, pkg);
		pkg = NULL;
	}

	if (pkg_jobs_is_empty(jobs)) {
		printf("\n>>> Unable to find packages for installation.\n\n");
		return (EPKG_FATAL);
	}

	/* print a summary before applying the jobs */
	pkg = NULL;

	print_jobs_summary(jobs, PKG_JOBS_INSTALL, "The following packages will be installed:\n\n");
	
	if (yes == false)
		yes = query_yesno("\n>>> Try to fix the missing dependencies [y/N]: ");

	if (yes == true)
		pkg_jobs_apply(jobs, 0);

	free(pkgs);
	pkg_free(pkg);
	pkg_jobs_free(jobs);
	pkgdb_it_free(it);

	return (EPKG_OK);
}
Пример #7
0
Файл: add.c Проект: culot/pkgng
int
exec_add(int argc, char **argv)
{
    struct pkgdb *db = NULL;
    struct sbuf *failedpkgs = sbuf_new_auto();
    char path[MAXPATHLEN + 1];
    char *file;
    int retcode = EPKG_OK;
    int i;
    int failedpkgcount = 0;
    struct pkg *p = NULL;

    if (argc < 2) {
        usage_add();
        return (EX_USAGE);
    }

    if (geteuid() != 0) {
        warnx("adding packages can only be done as root");
        return (EX_NOPERM);
    }

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

    for (i = 1; i < argc; i++) {
        if (is_url(argv[i]) == EPKG_OK) {
            snprintf(path, sizeof(path), "./%s", basename(argv[i]));
            if ((retcode = pkg_fetch_file(argv[i], path)) != EPKG_OK)
                break;

            file = path;
        } else
            file = argv[i];

        pkg_open(&p, file, NULL);

        if ((retcode = pkg_add(db, file, 0)) != EPKG_OK) {
            sbuf_cat(failedpkgs, argv[i]);
            if (i != argc - 1)
                sbuf_printf(failedpkgs, ", ");
            failedpkgcount++;
        }

    }

    pkgdb_close(db);

    if(failedpkgcount > 0) {
        sbuf_finish(failedpkgs);
        printf("Failed to install the following %d package(s): %s.\n", failedpkgcount, sbuf_data(failedpkgs));
    }
    sbuf_delete(failedpkgs);

    return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE);
}
Пример #8
0
static int
pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt, const char * const outdir, const char * const rootdir)
{
	int i, ret = EPKG_OK, retcode = EPKG_OK;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	int query_flags = PKG_LOAD_DEPS | PKG_LOAD_CONFLICTS | PKG_LOAD_FILES | PKG_LOAD_CATEGORIES |
					  PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS |
					  PKG_LOAD_MTREE | PKG_LOAD_LICENSES;

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

	if (match != MATCH_ALL) {
		for (i = 0;i < argc; i++) {
			if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
				goto cleanup;
			}
			while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
				printf("Creating package for %s-%s\n", pkg_get(pkg, PKG_NAME),
				    pkg_get(pkg, PKG_VERSION));
				if (pkg_create_installed(outdir, fmt, rootdir, pkg) != EPKG_OK) {
					retcode++;
				}
			}
		}
	} else {
		if ((it = pkgdb_query(db, NULL, match)) == NULL) {
			goto cleanup;
		}
		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
			printf("Creating package for %s-%s\n", pkg_get(pkg, PKG_NAME),
					pkg_get(pkg, PKG_VERSION));
			if (pkg_create_installed(outdir, fmt, rootdir, pkg) != EPKG_OK) {
				retcode++;
			}
		}
	}

cleanup:
	if (ret != EPKG_END) {
		retcode++;
	}

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

	return (retcode);
}
Пример #9
0
int
exec_stats(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	int64_t flatsize = 0;
	char size[7];
	int retcode = EX_OK;
	int ch;

	while ((ch = getopt(argc, argv, "q")) != -1) {
                switch (ch) {
		case 'q':
			quiet = true;
			break;
		default:
			usage_stats();
			return (EX_USAGE);
                }
        }
        argc -= optind;
        argv += optind;

	if (argc > 2) {
		usage_stats();
		return (EX_USAGE);
	}

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

	printf("Local package database:\n");
	printf("\tInstalled packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_LOCAL_COUNT));

	flatsize = pkgdb_stats(db, PKG_STATS_LOCAL_SIZE);
	humanize_number(size, sizeof(flatsize), flatsize, "B", HN_AUTOSCALE, 0);
	printf("\tDisk space occupied: %s\n\n", size);

	printf("Remote package database(s):\n");
	printf("\tNumber of repositories: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_REPOS));
	printf("\tPackages available: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_COUNT));
	printf("\tUnique packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_UNIQUE));

	flatsize = pkgdb_stats(db, PKG_STATS_REMOTE_SIZE);
	humanize_number(size, sizeof(flatsize), flatsize, "B", HN_AUTOSCALE, 0);
	printf("\tTotal size of packages: %s\n", size);

	pkgdb_close(db);

	return (retcode);
}
Пример #10
0
int
exec_shlib(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	char		 libname[MAXPATHLEN + 1];
	int		 retcode = EPKG_OK;
	int		 ch;
	bool		 provides_only = false;
	bool		 requires_only = false;

	while ((ch = getopt(argc, argv, "PR")) != -1) {
		switch (ch) {
		case 'P':
			provides_only = true;
			break;
		case 'R':
			requires_only = true;
			break;
		default:
			usage_shlib();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1 || (provides_only && requires_only)) {
		usage_shlib();
		return (EX_USAGE);
	}

	if (sanitize(libname, argv[0], sizeof(libname)) == NULL) {
		usage_shlib();
		return (EX_USAGE);
	}

	retcode = pkgdb_open(&db, PKGDB_DEFAULT);

	if (retcode == EPKG_OK && !provides_only)
		retcode = pkgs_providing_lib(db, libname);

	if (retcode == EPKG_OK && !requires_only)
		retcode = pkgs_requiring_lib(db, libname);

	if (retcode != EPKG_OK)
		retcode = (EX_IOERR);
		
	pkgdb_close(db);
	return (retcode);
}
Пример #11
0
static
int load_db_packages(struct pm_ctx *pmctx, struct pkgdir *pkgdir,
                     const char *rootdir) 
{
    struct pkgdb       *db;
    struct pkgdb_it    it;
    const struct pm_dbrec *dbrec;
    char               dbfull_path[PATH_MAX];    
    int                n;
    
    snprintf(dbfull_path, sizeof(dbfull_path), "%s%s",
             *(rootdir + 1) == '\0' ? "" : rootdir,
             pkgdir->idxpath != NULL ? pkgdir->idxpath : "");

    db = pkgdb_open(pmctx, rootdir, pkgdir->idxpath, O_RDONLY, NULL);
    if (db == NULL)
        return 0;

    msg(3, _("Loading db packages%s%s%s..."), *dbfull_path ? " [":"",
        dbfull_path, *dbfull_path ? "]":"");

    pkgdb_it_init(db, &it, PMTAG_RECNO, NULL);

    n = 0;
    while ((dbrec = pkgdb_it_get(&it))) {
        if (dbrec->hdr) {
            if (load_package(dbrec->recno, dbrec->hdr, pkgdir))
                n++;
        }

        if (n % 100 == 0)
            msg(3, "_.");
        
        if (sigint_reached()) {
            n = 0;
            break;
        }
    }
    msgn(3, "_done");
    
    pkgdb_it_destroy(&it);
    pkgdb_free(db);

    if (n == 0)
        n_array_clean(pkgdir->pkgs);
    
    return n_array_size(pkgdir->pkgs);
}
Пример #12
0
/* just check if database exists */
static
int do_open(struct pkgdir *pkgdir, unsigned flags)
{
    struct pm_ctx *pmctx;
    struct pkgdb  *db;


    flags = flags;          /* unused */
    
    n_assert(pkgdir->mod_data == NULL);
    pkgdir->mod_data = pmctx = pm_new("rpm");
    
    if ((db = pkgdb_open(pmctx, "/", pkgdir->idxpath, O_RDONLY, NULL)) == NULL)
        return 0;

    pkgdb_free(db);
    return 1;
}
Пример #13
0
Файл: pkgdb.c Проект: 41px/pkgin
/* dump contents of the database to stdout */
int
pkgdb_dump(void)
{
	DBT     key;
	DBT	val;
	int	type;

	if (pkgdb_open(ReadOnly)) {
		for (type = R_FIRST ; (*pkgdbp->seq)(pkgdbp, &key, &val, type) == 0 ; type = R_NEXT) {
			printf("file: %.*s pkg: %.*s\n",
				(int) key.size, (char *) key.data,
				(int) val.size, (char *) val.data);
		}
		pkgdb_close();
		return 0;
	} else
		return -1;
}
Пример #14
0
int
getdb(struct pkgdb **db)
{
	int err;

	/* err = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);

	if (err == EPKG_ENOACCESS)
		fprintf(stderr, "check your privilege\n", err);
	else if (err != EPKG_OK)
		fprintf(stderr, "access error: %i\n", err);
	else */{
		err = pkgdb_open(db, PKGDB_REMOTE);
		if (err != EPKG_OK)
			fprintf(stderr, "open error: %i\n", err);
	}
	return err;
}
Пример #15
0
int
exec_which(int argc, char **argv)
{
	struct pkgdb *db;
	struct pkgdb_it *it;
	struct pkg *pkg = NULL;
	char pathabs[MAXPATHLEN + 1];
	int ret = EPKG_OK, retcode = EPKG_OK;
	const char *name, *version;

	if (argc != 2) {
		usage_which();
		return (EX_USAGE);
	}

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

	absolutepath(argv[1], pathabs, sizeof(pathabs));

	if ((it = pkgdb_query_which(db, pathabs)) == NULL) {
		return (EX_IOERR);
	}

	if (( ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
		retcode = EPKG_OK;
		pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version);
		printf("%s was installed by package %s-%s\n", pathabs, name, version);
	} else if (ret != EPKG_END) {
		retcode = EPKG_WARN;
	} else {
		printf("%s was not found in the database\n", pathabs);
		retcode = EPKG_WARN;
	}
		
	pkg_free(pkg);
	pkgdb_it_free(it);

	pkgdb_close(db);
	return (retcode);
}
Пример #16
0
/* Add indexes to the repo */
static int
remote_add_indexes(const char *reponame)
{
	struct pkgdb *db = NULL;
	int ret = EPKG_FATAL;

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		goto cleanup;

	/* Initialize the remote remote */
	if (pkgdb_remote_init(db, reponame) != EPKG_OK)
		goto cleanup;

	ret = EPKG_OK;

	cleanup:
	if (db)
		pkgdb_close(db);
	return (ret);
}
Пример #17
0
static int
convert_from_old(const char *pkg_add_dbdir, bool dry_run)
{
	DIR *d;
	struct dirent *dp;
	struct pkg *p = NULL;
	char path[MAXPATHLEN];
	struct pkgdb *db = NULL;

	if ((d = opendir(pkg_add_dbdir)) == NULL)
		err(EX_NOINPUT, "%s", pkg_add_dbdir);

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		return (EX_IOERR);
	}
	while ((dp = readdir(d)) != NULL) {
		if (dp->d_type == DT_DIR) {
			if (strcmp(dp->d_name, ".") == 0 ||
			    strcmp(dp->d_name, "..") == 0)
				continue;
			if (p == NULL) {
				if (pkg_new(&p, PKG_OLD_FILE) != EPKG_OK)
					err(EX_OSERR, "malloc");
			} else
				pkg_reset(p, PKG_OLD_FILE);
			printf("Converting %s...\n", dp->d_name);
			snprintf(path, MAXPATHLEN, "%s/%s", pkg_add_dbdir, dp->d_name);
			if (pkg_old_load_from_path(p, path) != EPKG_OK) {
				fprintf(stderr, "Skipping invalid package: %s\n", path);
				continue;
			}
			pkg_from_old(p);
			if (!dry_run)
				pkgdb_register_ports(db, p);
		}
	}

	pkg_free(p);
	pkgdb_close(db);
	return (EX_OK);
}
Пример #18
0
int
exec_backup(int argc, char **argv)
{
	struct pkgdb  *db = NULL;
	char *dest = NULL;

	if (argc < 2 || argc > 3 || argv[1][0] != '-') {
		usage_backup();
		return (EX_USAGE);
	}

	if (argc == 3)
		dest = argv[2];

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

	if (argv[1][1] == 'd') {
		if (isatty(fileno(stdin)))
				printf("Dumping database...\n");
		if (pkgdb_dump(db, dest) == EPKG_FATAL)
			return (EX_IOERR);

		if (isatty(fileno(stdin)))
			printf("done\n");
	}

	if (argv[1][1] == 'r') {
		if (isatty(fileno(stdin)))
			printf("Restoring database...\n");
		if (pkgdb_load(db, dest) == EPKG_FATAL)
			return (EX_IOERR);
		if (isatty(fileno(stdin)))
			printf("done\n");
	}

	pkgdb_close(db);

	return (EX_OK);
}
Пример #19
0
static Header ldhdr(const struct pkg *pkg, void *foo) 
{
    struct pm_ctx    *pmctx;
    struct pkgdb     *db;
    struct pkgdb_it  it;
    const struct pm_dbrec *dbrec;
    Header              h = NULL;

    foo = foo;
    n_assert(pkg->recno > 0);
    
    if (pkg->pkgdir == NULL)
        return NULL;

    pmctx = pkg->pkgdir->mod_data;
    if (pkg->pkgdir->mod_data == NULL) /* pkgdir are saved now  */
        pmctx = pm_new("rpm");
    
    db = pkgdb_open(pmctx, "/", pkg->pkgdir->idxpath,
                    O_RDONLY, NULL);
    if (db == NULL)
        return NULL;
    
    pkgdb_it_init(db, &it, PMTAG_RECNO, (const char*)&pkg->recno);
    dbrec = pkgdb_it_get(&it);
    
    // rpm's error: rpmdb_it_get_count(&it) with RECNO is always 0 
    if (dbrec && dbrec->hdr)
        h = pm_rpmhdr_link(dbrec->hdr);

    pkgdb_it_destroy(&it);
    pkgdb_free(db);
    if (pkg->pkgdir->mod_data == NULL)
        pm_free(pmctx);
    return h;
}
Пример #20
0
/*
 * Delete the results of a package installation.
 *
 * This is here rather than in the pkg_delete code because pkg_add needs to
 * run it too in cases of failure.
 */
int
delete_package(Boolean ign_err, package_t *pkg, Boolean NoDeleteFiles,
    const char *destdir)
{
	plist_t *p;
	const char *last_file = "";
	int     fail = SUCCESS;
	Boolean preserve;
	char    tmp[MaxPathSize];
	const char *prefix = NULL, *name = NULL;

	if (!pkgdb_open(ReadWrite)) {
		err(EXIT_FAILURE, "cannot open pkgdb");
	}

	preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE;

	for (p = pkg->head; p; p = p->next) {
		switch (p->type) {
		case PLIST_NAME:
			name = p->name;
			break;
		case PLIST_CWD:
			if (prefix == NULL)
				prefix = p->name;
			break;
		default:
			break;
		}
	}

	if (name == NULL || prefix == NULL)
		errx(EXIT_FAILURE, "broken PLIST");

	/*
	 * Remove database entries first, directory removal is done
	 * in the main loop below.
	 */
	for (p = pkg->head; p; p = p->next) {
		if (p->type == PLIST_PKGDIR)
			delete_pkgdir(name, prefix, p->name);
	}

	for (p = pkg->head; p; p = p->next) {
		switch (p->type) {
		case PLIST_NAME:
			/* Handled already */
			break;

		case PLIST_PKGDIR:
		case PLIST_DIR_RM:
			(void) snprintf(tmp, sizeof(tmp), "%s/%s",
			    prefix, p->name);
			if (has_pkgdir(tmp))
				continue;
			(void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s",
			    destdir ? destdir : "", destdir ? "/" : "",
			    prefix, p->name);
			if (!fexists(tmp)) {
				if (p->type == PLIST_PKGDIR)
					warnx("Directory `%s' disappeared, skipping", tmp);
			} else if (!isdir(tmp)) {
				warnx("attempting to delete a file `%s' as a directory\n"
				    "this packing list is incorrect - ignoring delete request", tmp);
			} else if (delete_with_parents(tmp, ign_err, TRUE))
				fail = FAIL;
			break;

		case PLIST_IGNORE:
			p = p->next;
			break;

		case PLIST_UNEXEC:
			if (NoDeleteFiles)
				break;
			format_cmd(tmp, sizeof(tmp), p->name, prefix, last_file);
			printf("Executing `%s'\n", tmp);
			if (!Fake && system(tmp)) {
				warnx("unexec command for `%s' failed", tmp);
				fail = FAIL;
			}
			break;

		case PLIST_FILE:
			last_file = p->name;
			(void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s",
			    destdir ? destdir : "", destdir ? "/" : "",
			    prefix, p->name);
			if (isdir(tmp)) {
				warnx("attempting to delete directory `%s' as a file\n"
				    "this packing list is incorrect - ignoring delete request", tmp);
			} else {
				int     restored = 0;	/* restored from preserve? */

				if (p->next && p->next->type == PLIST_COMMENT) {
					if (strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
						char   *cp, buf[LegibleChecksumLen];

						if ((cp = MD5File(tmp, buf)) != NULL) {
							/* Mismatch? */
							if (strcmp(cp, p->next->name + ChecksumHeaderLen) != 0) {
								printf("original MD5 checksum failed, %s: %s\n",
								    Force ? "deleting anyway" : "not deleting", tmp);
								if (!Force) {
									fail = FAIL;
									goto pkgdb_cleanup;
								}
							}
						}
					} else if (strncmp(p->next->name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
						char	buf[MaxPathSize + SymlinkHeaderLen];
						int	cc;

						(void) strlcpy(buf, SYMLINK_HEADER,
						    sizeof(buf));
						if ((cc = readlink(tmp, &buf[SymlinkHeaderLen],
							  sizeof(buf) - SymlinkHeaderLen - 1)) < 0) {
							warn("can't readlink `%s'", tmp);
							goto pkgdb_cleanup;
						}
						buf[SymlinkHeaderLen + cc] = 0x0;
						if (strcmp(buf, p->next->name) != 0) {
							if ((cc = readlink(&buf[SymlinkHeaderLen], &buf[SymlinkHeaderLen],
								  sizeof(buf) - SymlinkHeaderLen)) < 0) {
								printf("symlink %s is not same as recorded value, %s: %s\n",
								    buf, Force ? "deleting anyway" : "not deleting", tmp);
								if (!Force) {
									fail = FAIL;
									goto pkgdb_cleanup;
								}
							}
							buf[SymlinkHeaderLen + cc] = 0x0;
							if (strcmp(buf, p->next->name) != 0) {
								printf("symlink %s is not same as recorded value, %s: %s\n",
								    buf, Force ? "deleting anyway" : "not deleting", tmp);
								if (!Force) {
									fail = FAIL;
									goto pkgdb_cleanup;
								}
							}
						}
					}
				}
				if (Verbose && !NoDeleteFiles)
					printf("Delete file %s\n", tmp);
				if (!Fake && !NoDeleteFiles) {
					if (delete_with_parents(tmp, ign_err, FALSE))
						fail = FAIL;
					if (preserve && name) {
						char    tmp2[MaxPathSize];

						if (make_preserve_name(tmp2, MaxPathSize, name, tmp)) {
							if (fexists(tmp2)) {
								if (rename(tmp2, tmp))
									warn("preserve: unable to restore %s as %s",
									    tmp2, tmp);
								else
									restored = 1;
							}
						}
					}
				}

pkgdb_cleanup:
				if (!Fake) {
					if (!restored) {
						errno = 0;
						if (pkgdb_remove(tmp) && errno)
							perror("pkgdb_remove");
					}
				}
			}
			break;
		default:
			break;
		}
	}
	pkgdb_close();
	return fail;
}
Пример #21
0
int
exec_query(int argc, char **argv)
{
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	char *pkgname = NULL;
	int query_flags = PKG_LOAD_BASIC;
	match_t match = MATCH_EXACT;
	int ch;
	int ret = EPKG_OK;
	int retcode = EXIT_SUCCESS;
	int i;
	char multiline = 0;

	while ((ch = getopt(argc, argv, "agxXf:")) != -1) {
		switch (ch) {
			case 'a':
				match = MATCH_ALL;
				break;
			case 'g':
				match = MATCH_GLOB;
				break;
			case 'x':
				match = MATCH_REGEX;
				break;
			case 'X':
				match = MATCH_EREGEX;
				break;
			case 'f':
				pkgname = optarg;
				break;
			default:
				usage_query();
				return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0) {
		usage_query();
		return (EX_USAGE);
	}

	if ((argc == 1) ^ (match == MATCH_ALL) && pkgname == NULL) {
		usage_query();
		return (EX_USAGE);
	}

	if (analyse_query_string(argv[0], &query_flags, &multiline) != EPKG_OK)
		return (EX_USAGE);

	if (pkgname != NULL) {
		if (pkg_open(&pkg, pkgname, NULL) != EPKG_OK) {
			return (1);
		}
		
		print_query(pkg, argv[0], multiline);
		pkg_free(pkg);
		return (0);
	}

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

	if (match == MATCH_ALL) {
		if ((it = pkgdb_query(db, NULL, match)) == NULL)
			return (EX_IOERR);

		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK)
			print_query(pkg, argv[0],  multiline);

		if (ret != EPKG_END)
			retcode = EX_SOFTWARE;

		pkgdb_it_free(it);
	} else {
		for (i = 1; i < argc; i++) {
			pkgname = argv[i];

			if ((it = pkgdb_query(db, pkgname, match)) == NULL)
				return (EX_IOERR);

			while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK)
				print_query(pkg, argv[0], multiline);

			if (ret != EPKG_END) {
				retcode = EX_SOFTWARE;
				break;
			}

			pkgdb_it_free(it);
		}
	}

	pkg_free(pkg);
	pkgdb_close(db);

	return (retcode);
}
Пример #22
0
int
exec_set(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	int		 ch;
	int		 i;
	match_t		 match = MATCH_EXACT;
	int64_t		 newautomatic = -1;
	bool		 automatic = false;
	bool		 rc = false;
	const char	*changed = NULL;
	char		*newvalue = NULL;
	char		*oldvalue = NULL;
	unsigned int	 loads = PKG_LOAD_BASIC;
	unsigned int	 sets = 0;
	unsigned int	 field = 0, depfield = 0;
	int		 retcode;

	struct option longopts[] = {
		{ "automatic",		required_argument,	NULL,	'A' },
		{ "all",		no_argument,		NULL,	'a' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "change-origin",	required_argument,	NULL,	'o' },
		{ "change-name",	required_argument,	NULL,	'n' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ "yes",		no_argument,		NULL,	'y' },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+A:aCgio:xyn:", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
			sets |= AUTOMATIC;
			newautomatic = optarg[0] - '0';
			if (newautomatic != 0 && newautomatic != 1)
				errx(EX_USAGE, "Wrong value for -A. "
				    "Expecting 0 or 1, got: %s",
				    optarg);
			break;
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'o':
			sets |= ORIGIN;
			loads |= PKG_LOAD_DEPS;
			match = MATCH_ALL;
			changed = "origin";
			if (!check_change_values(optarg, &oldvalue, &newvalue, '/')) {
				 errx(EX_USAGE, "Wrong format for -o. "
					 "Expecting oldorigin:neworigin, got: %s",
					 optarg);
			}
			break;
		case 'n':
			sets |= NAME;
			loads |= PKG_LOAD_DEPS;
			match = MATCH_ALL;
			changed = "name";
			if (!check_change_values(optarg, &oldvalue, &newvalue, '\0')) {
				 errx(EX_USAGE, "Wrong format for -n. "
					 "Expecting oldname:newname, got: %s",
					 optarg);
			}
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			free(oldvalue);
			
			usage_set();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if ((argc < 1 && match != MATCH_ALL) ||
		(newautomatic == -1 && newvalue == NULL) ||
		(sets & (NAME|ORIGIN)) == (NAME|ORIGIN)) {
		usage_set();
		return (EX_USAGE);
	}

	if (sets & NAME) {
		field = PKG_SET_NAME;
		depfield = PKG_SET_DEPNAME;
	}
	else if (sets & ORIGIN) {
		field = PKG_SET_ORIGIN;
		depfield = PKG_SET_DEPORIGIN;
	}

	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
			       PKGDB_DB_LOCAL);
	if (retcode == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
		if (!quiet)
			warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to modify the package database");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing package database");
		return (EX_SOFTWARE);
	}

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

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
		pkgdb_close(db);
		free(newvalue);
		warnx("Cannot get an exclusive lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (pkgdb_transaction_begin(db, NULL) != EPKG_OK) {
		pkgdb_close(db);
		free(newvalue);
		warnx("Cannot start transaction for update");
		return (EX_TEMPFAIL);
	}

 
	if (oldvalue != NULL) {
		match = MATCH_ALL;
		if ((it = pkgdb_query(db, oldvalue, MATCH_EXACT)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) {
			pkg = NULL;
/*			fprintf(stderr, "%s not installed\n", oldorigin);
			free(oldorigin);
			pkgdb_it_free(it);
			pkgdb_close(db);
			return (EX_SOFTWARE);*/
		}

		rc = yes;
		if (!yes) {
			if (pkg != NULL)
				rc = query_yesno(false, "Change %S from %S to %S for %n-%v? ",
						changed, oldvalue, newvalue, pkg, pkg);
			else
				rc = query_yesno(false, "Change %S from %S to %S for all dependencies? ",
						changed, oldvalue, newvalue);
		}
		if (pkg != NULL && rc) {
			if (pkgdb_set(db, pkg, field, newvalue) != EPKG_OK) {
				retcode = EX_IOERR;
				goto cleanup;
			}
		}
		pkgdb_it_free(it);
	}
	i = 0;
	do {
		bool saved_rc = rc;

		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			retcode = EX_IOERR;
			goto cleanup;
		}

		while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) {
			if ((sets & AUTOMATIC) == AUTOMATIC) {
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
				if (automatic == newautomatic)
					continue;
				if (!rc) {
					if (newautomatic)
						rc = query_yesno(false,
								"Mark %n-%v as automatically installed? ",
								pkg, pkg);
					else
						rc = query_yesno(false,
								"Mark %n-%v as not automatically installed? ",
								pkg, pkg);
				}
				if (rc)
					pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, (int)newautomatic);
				rc = saved_rc;
			}
			if (sets & (ORIGIN|NAME)) {
				struct pkg_dep *d = NULL;
				while (pkg_deps(pkg, &d) == EPKG_OK) {
					/*
					 * Do not query user when he has already
					 * been queried.
					 */
					if (pkgdb_set(db, pkg, depfield, oldvalue, newvalue) != EPKG_OK) {
						retcode = EX_IOERR;
						goto cleanup;
					}
				}
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

cleanup:
	free(oldvalue);
	free(newvalue);
	pkg_free(pkg);

	if (retcode == 0) {
		pkgdb_transaction_commit(db, NULL);
	}
	else {
		pkgdb_transaction_rollback(db, NULL);
	}

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);

	return (retcode);
}
Пример #23
0
int
exec_fetch(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
	struct pkg_jobs *jobs = NULL;
	const char *reponame = NULL;
	int retcode = EXIT_FAILURE;
	int ch;
	int flags = PKG_LOAD_BASIC;
	bool yes = false;
	bool auto_update = true;
	match_t match = MATCH_EXACT;

	while ((ch = getopt(argc, argv, "ygxXr:qaLd")) != -1) {
		switch (ch) {
		case 'y':
			yes = true;
			break;
		case 'a':
			match = MATCH_ALL;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'X':
			match = MATCH_EREGEX;
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'q':
			quiet = true;
			break;
		case 'L':
			auto_update = false;
			break;
		case 'd':
			flags |= PKG_LOAD_DEPS;
			break;
		default:
			usage_fetch();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;
	
	if (argc < 1 && match != MATCH_ALL) {
		usage_fetch();
		return (EX_USAGE);
	}

	/* TODO: Allow the user to specify an output directory via -o outdir */
	if (geteuid() != 0) {
		warnx("Fetching packages can only be done as root");
		return (EX_NOPERM);
	}

	/* first update the remote repositories if needed */
	if (auto_update && (retcode = pkgcli_update()) != EPKG_OK)
		return (retcode);

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

	if (pkg_jobs_new(&jobs, PKG_JOBS_FETCH, db) != EPKG_OK) {
		goto cleanup;
	}

	if ((it = pkgdb_query_fetch(db, match, argc, argv, reponame, flags)) == NULL)
		goto cleanup;

	while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
		pkg_jobs_add(jobs, pkg);
		pkg = NULL;
	}
	
	pkgdb_it_free(it);

	if (pkg_jobs_is_empty(jobs))
		goto cleanup;

	if (!quiet) {
		print_jobs_summary(jobs, PKG_JOBS_FETCH, "The following packages will be fetched:\n\n");
		
		if (!yes)
			pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
		if (!yes)
			yes = query_yesno("\nProceed with fetching packages [y/N]: ");
	}
	
	if (yes)
		if (pkg_jobs_apply(jobs, 0) != EPKG_OK)
			goto cleanup;

	retcode = EXIT_SUCCESS;

	cleanup:
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	return (retcode);
}
Пример #24
0
int
exec_register(int argc, char **argv)
{
	struct pkg	*pkg = NULL;
	struct pkgdb	*db  = NULL;

	struct pkg_manifest_key *keys = NULL;

	regex_t		 preg;
	regmatch_t	 pmatch[2];

	char		*arch = NULL;
	char		 myarch[BUFSIZ];
	char		*www  = NULL;
	char		 fpath[MAXPATHLEN];

	const char	*plist      = NULL;
	const char	*mdir       = NULL;
	const char	*mfile      = NULL;
	const char	*input_path = NULL;
	const char	*desc       = NULL;
	const char	*location   = NULL;

	size_t		 size;

	bool		 developer;
	bool		 legacy        = false;
	bool		 old           = false;
	bool		 __unused metadata_only = false;
	bool		 testing_mode  = false;

	int		 ch;
	int		 i;
	int		 ret     = EPKG_OK;
	int		 retcode = EX_OK;

	/* options descriptor */
	struct option longopts[] = {
		{ "automatic",	no_argument,		NULL,	'A' },
		{ "plist",	required_argument,	NULL,	'f' },
		{ "root",	required_argument,	NULL,	'i' },
		{ "legacy",	no_argument,		NULL,	'l' },
		{ "manifest",	required_argument,	NULL,	'M' },
		{ "metadata",	required_argument,	NULL,	'm' },
		{ "old",	no_argument,		NULL,	'O' },
		{ "test",	no_argument,		NULL,	't' },
		{ "relocate",	required_argument,	NULL, 	1 },
		{ NULL,		0,			NULL,	0},
	};

	developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));

	if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
		err(EX_OSERR, "malloc");

	while ((ch = getopt_long(argc, argv, "Adf:i:lM:m:Ot", longopts, NULL)) != -1) {
		switch (ch) {
		case 'A':
		case 'd':
			pkg_set(pkg, PKG_AUTOMATIC, (bool)true);
			break;
		case 'f':
			plist = optarg;
			break;
		case 'i':
			input_path = optarg;
			break;
		case 'l':
			legacy = true;
			break;
		case 'M':
			metadata_only = true;
			mfile = optarg;
			break;
		case 'm':
			mdir = optarg;
			break;
		case 'O':
			old = true;
			break;
		case 't':
			testing_mode = true;
			break;
		case 1:
			location = optarg;
			break;
		default:
			warnx("Unrecognised option -%c\n", ch);
			usage_register();
			return (EX_USAGE);
		}
	}

	if (!old) {
		retcode = pkgdb_access(PKGDB_MODE_READ  |
				       PKGDB_MODE_WRITE |
				       PKGDB_MODE_CREATE,
				       PKGDB_DB_LOCAL);
		if (retcode == EPKG_ENOACCESS) {
			warnx("Insufficient privileges to register packages");
			return (EX_NOPERM);
		} else if (retcode != EPKG_OK)
			return (EX_IOERR);
		else
			retcode = EX_OK;
	}

	/*
	 * Ideally, the +MANIFEST should be all that is necessary,
	 * since it can contain all of the meta-data supplied by the
	 * other files mentioned below.  These are here for backwards
	 * compatibility with the way the ports tree works with
	 * pkg_tools.
	 * 
	 * The -M option specifies one manifest file to read the
	 * meta-data from, and overrides the use of legacy meta-data
	 * inputs.
	 *
	 * Dependencies, shlibs, files etc. may be derived by
	 * analysing the package files (maybe discovered as the
	 * content of the staging directory) unless -t (testing_mode)
	 * is used.
	 */

	if (mfile != NULL && mdir != NULL) {
		warnx("Cannot use both -m and -M together");
		usage_register();
		return (EX_USAGE);
	}


	if (mfile == NULL && mdir == NULL) {
		warnx("One of either -m or -M flags is required");
		usage_register();
		return (EX_USAGE);
	}

	if (mfile != NULL && plist != NULL) {
		warnx("-M incompatible with -f option");
		usage_register();
		return (EX_USAGE);
	}

	if (testing_mode && input_path != NULL) {
		warnx("-i incompatible with -t option");
		usage_register();
		return (EX_USAGE);
	}

	pkg_manifest_keys_new(&keys);

	if (mfile != NULL) {
		ret = pkg_parse_manifest_file(pkg, mfile, keys);
		pkg_manifest_keys_free(keys);
		if (ret != EPKG_OK) 
			return (EX_IOERR);

	} else {
		snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir);
		ret = pkg_parse_manifest_file(pkg, fpath, keys);
		pkg_manifest_keys_free(keys);
		if (ret != EPKG_OK)
			return (EX_IOERR);


		snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir);
		pkg_set_from_file(pkg, PKG_DESC, fpath, false);

		snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir);
		if (access(fpath, F_OK) == 0)
			pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false);

		snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir);
		if (access(fpath, F_OK) == 0)
			pkg_set_from_file(pkg, PKG_MTREE, fpath, false);

		for (i = 0; scripts[i] != NULL; i++) {
			snprintf(fpath, sizeof(fpath), "%s/%s", mdir,
			    scripts[i]);
			if (access(fpath, F_OK) == 0)
				pkg_addscript_file(pkg, fpath);
		}

		if (www != NULL) {
			pkg_set(pkg, PKG_WWW, www);
			free(www);
		}

		pkg_get(pkg, PKG_WWW, &www);

		/* 
		 * if www is not given then try to determine it from
		 * description
		 */

		if (www == NULL) {
			pkg_get(pkg, PKG_DESC, &desc);
			regcomp(&preg, "^WWW:[[:space:]]*(.*)$",
			    REG_EXTENDED|REG_ICASE|REG_NEWLINE);
			if (regexec(&preg, desc, 2, pmatch, 0) == 0) {
				size = pmatch[1].rm_eo - pmatch[1].rm_so;
				www = strndup(&desc[pmatch[1].rm_so], size);
				pkg_set(pkg, PKG_WWW, www);
				free(www);
			} else {
				pkg_set(pkg, PKG_WWW, "UNKNOWN");
			}
			regfree(&preg);
		}

		if (plist != NULL)
			ret += ports_parse_plist(pkg, plist, input_path);
	}

	if (ret != EPKG_OK) {
		return (EX_IOERR);
	}


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

		if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
			pkgdb_close(db);
			warnx("Cannot get an exclusive lock on a database, it is locked by another process");
			return (EX_TEMPFAIL);
		}
	}

	/*
	 * testing_mode allows updating the local package database
	 * without any check that the files etc. listed in the meta
	 * data actually exist on the system.  Inappropriate use of
	 * testing_mode can really screw things up.
	 */

	if (!testing_mode)
		pkg_analyse_files(db, pkg, input_path);

	pkg_get(pkg, PKG_ARCH, &arch);
	if (arch == NULL) {
		/*
		 * do not take the one from configuration on purpose
		 * but the real abi of the package.
		 */
		pkg_get_myarch(myarch, BUFSIZ);
		if (developer)
			pkg_suggest_arch(pkg, myarch, true);
		pkg_set(pkg, PKG_ARCH, myarch);
	} else {
		if (developer)
			pkg_suggest_arch(pkg, arch, false);
	}

	if (!testing_mode && input_path != NULL)
		pkg_copy_tree(pkg, input_path, location ? location : "/");
	
	if (location != NULL)
		pkg_addannotation(pkg, "relocated", location);

	if (old) {
		if (pkg_register_old(pkg) != EPKG_OK)
			retcode = EX_SOFTWARE;
	} else {
		if (pkgdb_register_ports(db, pkg) != EPKG_OK)
			retcode = EX_SOFTWARE;
	}

	if (!legacy && pkg_has_message(pkg))
		pkg_printf("%M\n", pkg);

	if (!old) {
		pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
		pkgdb_close(db);
	}

	pkg_free(pkg);

	return (retcode);
}
Пример #25
0
int
exec_stats(int argc, char **argv)
{
	struct pkgdb	*db = NULL;
	int64_t		 flatsize = 0;
	unsigned int	 opt = 0;
	char		 size[7];
	int		 ch;
	bool		 show_bytes = false;

	struct option longopts[] = {
		{ "bytes",	no_argument,	NULL,	'b' },
		{ "local",	no_argument,	NULL,	'l' },
		{ "quiet",	no_argument,	NULL,	'q' },
		{ "remote",	no_argument,	NULL,	'r' },
		{ NULL,		0,		NULL,	0   },
	};
	
	while ((ch = getopt_long(argc, argv, "+blqr", longopts, NULL)) != -1) {
                switch (ch) {
		case 'b':
			show_bytes = true;
			break;
		case 'l':
			opt |= STATS_LOCAL;
			break;
		case 'q':
			quiet = true;
			break;
		case 'r':
			opt |= STATS_REMOTE;
			break;
		default:
			usage_stats();
			return (EX_USAGE);
                }
        }
        argc -= optind;
        argv += optind;

	/* default is to show everything we have */
	if (opt == 0)
		opt |= (STATS_LOCAL | STATS_REMOTE);

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

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get a read lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (opt & STATS_LOCAL) {
		printf("Local package database:\n");
		printf("\tInstalled packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_LOCAL_COUNT));

		flatsize = pkgdb_stats(db, PKG_STATS_LOCAL_SIZE);

		if (show_bytes)
			printf("\tDisk space occupied: %" PRId64 "\n\n", flatsize);
		else {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("\tDisk space occupied: %s\n\n", size);
		}
	}

	if ((opt & STATS_REMOTE) && pkg_repos_total_count() > 0) {
		printf("Remote package database(s):\n");
		printf("\tNumber of repositories: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_REPOS));
		printf("\tPackages available: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_COUNT));
		printf("\tUnique packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_UNIQUE));

		flatsize = pkgdb_stats(db, PKG_STATS_REMOTE_SIZE);

		if (show_bytes)
			printf("\tTotal size of packages: %" PRId64 "\n", flatsize);
		else {
			humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
			printf("\tTotal size of packages: %s\n", size);
		}
	}

	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
	pkgdb_close(db);

	return (EX_OK);
}
Пример #26
0
int
exec_search(int argc, char **argv)
{
	const char *pattern = NULL;
	const char *reponame = NULL;
	int ret = EPKG_OK, ch;
	int flags;
	unsigned int opt = 0;
	match_t match = MATCH_REGEX;
	pkgdb_field search = FIELD_NONE;
	pkgdb_field label = FIELD_NONE;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *pkg = NULL;
	bool atleastone = false;

	while ((ch = getopt(argc, argv, "cDdefgiL:opqQ:r:S:sx")) != -1) {
		switch (ch) {
		case 'c':	/* Same as -S comment */
			search = search_label_opt("comment");
			break;
		case 'D':	/* Same as -S description */
			search = search_label_opt("description");
			break;
		case 'd':	/* Same as -Q depends-on  */
			opt |= modifier_opt("depends-on");
			break;
		case 'e':
			match = MATCH_EXACT;
			break;
		case 'f':	/* Same as -Q full */
			opt |= modifier_opt("full");
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'L':
			label = search_label_opt(optarg);
			break;
		case 'o':	/* Same as -L origin */
			label = search_label_opt("origin");
			break;
		case 'p':	/* Same as -Q prefix */
			opt |= modifier_opt("prefix");
			break;
		case 'q':
			quiet = true;
			break;
		case 'Q':
			opt |= modifier_opt(optarg);
			break;
		case 'r':
			reponame = optarg;
			break;
		case 'S':
			search = search_label_opt(optarg);
			break;
		case 's':	/* Same as -Q size */
			opt |= modifier_opt("size");
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		default:
			usage_search();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage_search();
		return (EX_USAGE);
	}

	pattern = argv[0];
	if (pattern[0] == '\0') {
		fprintf(stderr, "Pattern must not be empty!\n");
		return (EX_USAGE);
	}
	if (search == FIELD_NONE) {
		if (strchr(pattern, '/') != NULL)
			search = FIELD_ORIGIN;
		else
			search = FIELD_NAMEVER; /* Default search */
	}
	if (label == FIELD_NONE)
		label = search; /* By default, show what was searched  */

	switch(label) {
	case FIELD_NONE:
		break;		/* should never happen */
	case FIELD_ORIGIN:
		opt |= INFO_TAG_ORIGIN;
		break;
	case FIELD_NAME:
		opt |= INFO_TAG_NAME;
		break;
	case FIELD_NAMEVER:
		opt |= INFO_TAG_NAMEVER;
		break;
	case FIELD_COMMENT:
		opt |= INFO_TAG_NAMEVER|INFO_COMMENT;
		break;
	case FIELD_DESC:
		opt |= INFO_TAG_NAMEVER|INFO_DESCR;
		break;
	}

	if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK)
		return (EX_IOERR);

	if ((it = pkgdb_search(db, pattern, match, search, search,
	    reponame)) == NULL) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	flags = info_flags(opt);
	while ((ret = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) {
		print_info(pkg, opt);
		atleastone = true;
	}

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

	if (!atleastone)
		ret = EPKG_FATAL;

	return ((ret == EPKG_OK || ret == EPKG_END) ? EX_OK : EX_SOFTWARE);
}
Пример #27
0
int
exec_delete(int argc, char **argv)
{
	struct pkg_jobs	*jobs = NULL;
	struct pkgdb	*db = NULL;
	match_t		 match = MATCH_EXACT;
	pkg_flags	 f = PKG_FLAG_NONE;
	bool		 recursive_flag = false, rc = false;
	int		 retcode = EX_SOFTWARE;
	int		 ch;
	int		 i;
	int		 lock_type = PKGDB_LOCK_ADVISORY;

	struct option longopts[] = {
		{ "all",			no_argument,	NULL,	'a' },
		{ "case-sensitive",		no_argument,	NULL,	'C' },
		{ "no-deinstall-script",	no_argument,	NULL,	'D' },
		{ "force",			no_argument,	NULL,	'f' },
		{ "glob",			no_argument,	NULL,	'g' },
		{ "case-insensitive",		no_argument,	NULL,	'i' },
		{ "dry-run",			no_argument,	NULL,	'n' },
		{ "quiet",			no_argument,	NULL,	'q' },
		{ "recursive",			no_argument,	NULL,	'R' },
		{ "regex",			no_argument,	NULL,	'x' },
		{ "yes",			no_argument,	NULL,	'y' },
		{ NULL,				0,		NULL,	0   },
	};

	nbactions = nbdone = 0;

	while ((ch = getopt_long(argc, argv, "+aCDfginqRxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'D':
			f |= PKG_FLAG_NOSCRIPT;
			break;
		case 'f':
			f |= PKG_FLAG_FORCE;
			force = true;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'n':
			f |= PKG_FLAG_DRY_RUN;
			lock_type = PKGDB_LOCK_READONLY;
			dry_run = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'R':
			recursive_flag = true;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_delete();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1 && match != MATCH_ALL) {
		usage_delete();
		return (EX_USAGE);
	}

	if (dry_run)
		retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	else
		retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
				       PKGDB_DB_LOCAL);

	if (retcode == EPKG_ENODB) {
		warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to delete packages");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

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

	if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an advisory lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}


	if (pkg_jobs_new(&jobs, PKG_JOBS_DEINSTALL, db) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}

	/*
	 * By default delete packages recursively.
	 * If force mode is enabled then we try to remove packages non-recursively.
	 * However, if -f and -R flags are both enabled then we return to
	 * recursive deletion.
	 */
	if (!force || recursive_flag)
		f |= PKG_FLAG_RECURSIVE;

	pkg_jobs_set_flags(jobs, f);

	if (match == MATCH_EXACT) {
		for (i = 0; i < argc; i++) {
			if (strchr(argv[i], '*') != NULL) {
				match = MATCH_GLOB;
				break;
			}
		}
	}

	if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL)
		goto cleanup;

	if (pkg_jobs_solve(jobs) != EPKG_OK) {
		fprintf(stderr, "Cannot perform request\n");
		retcode = EX_NOPERM;
		goto cleanup;
	}

	/* check if we have something to deinstall */
	if ((nbactions = pkg_jobs_count(jobs)) == 0) {
		if (argc == 0) {
			if (!quiet)
				printf("Nothing to do.\n");
			retcode = EX_OK;
		} else {
			fprintf(stderr, "Package(s) not found!\n");
			retcode = EX_DATAERR;
		}
		goto cleanup;
	}

	if (!quiet || dry_run) {
		if (!quiet) {
			print_jobs_summary(jobs,
				"Deinstallation has been requested for the following %d packages "
				"(of %d packages in the universe):\n\n", nbactions,
				pkg_jobs_total(jobs));
		}
		if (dry_run) {
			retcode = EX_OK;
			goto cleanup;
		}
		rc = query_yesno(false,
		            "\nProceed with deinstalling packages? ");
	}
	else
		rc = yes;

	if (!rc || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK)
		goto cleanup;

	pkgdb_compact(db);

	retcode = EX_OK;

cleanup:
	pkgdb_release_lock(db, lock_type);
	pkg_jobs_free(jobs);
	pkgdb_close(db);

	return (retcode);
}
Пример #28
0
int
exec_query(int argc, char **argv)
{
	struct pkgdb		*db = NULL;
	struct pkgdb_it		*it = NULL;
	struct pkg		*pkg = NULL;
	struct pkg_manifest_key	*keys = NULL;
	char			*pkgname = NULL;
	int			 query_flags = PKG_LOAD_BASIC;
	match_t			 match = MATCH_EXACT;
	int			 ch;
	int			 ret;
	int			 retcode = EX_OK;
	int			 i;
	char			 multiline = 0;
	char			*condition = NULL;
	struct sbuf		*sqlcond = NULL;
	const unsigned int	 q_flags_len = NELEM(accepted_query_flags);

	struct option longopts[] = {
		{ "all",		no_argument,		NULL,	'a' },
		{ "case-sensitive",	no_argument,		NULL,	'C' },
		{ "evaluate",		required_argument,	NULL,	'e' },
		{ "file",		required_argument,	NULL,	'F' },
		{ "glob",		no_argument,		NULL,	'g' },
		{ "case-insensitive",	no_argument,		NULL,	'i' },
		{ "regex",		no_argument,		NULL,	'x' },
		{ NULL,			0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "+aCe:F:gix", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'e':
			match = MATCH_CONDITION;
			condition = optarg;
			break;
		case 'F':
			pkgname = optarg;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		default:
			usage_query();
			return (EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 0) {
		usage_query();
		return (EX_USAGE);
	}

	/* Default to all packages if no pkg provided */
	if (argc == 1 && pkgname == NULL && condition == NULL && match == MATCH_EXACT) {
		match = MATCH_ALL;
	} else if (((argc == 1) ^ (match == MATCH_ALL)) && pkgname == NULL
			&& condition == NULL) {
		usage_query();
		return (EX_USAGE);
	}

	if (analyse_query_string(argv[0], accepted_query_flags, q_flags_len,
			&query_flags, &multiline) != EPKG_OK)
		return (EX_USAGE);

	if (pkgname != NULL) {
		pkg_manifest_keys_new(&keys);
		if (pkg_open(&pkg, pkgname, keys, 0) != EPKG_OK) {
			return (EX_IOERR);
		}

		pkg_manifest_keys_free(keys);
		print_query(pkg, argv[0], multiline);
		pkg_free(pkg);
		return (EX_OK);
	}

	if (condition != NULL) {
		sqlcond = sbuf_new_auto();
		if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) {
			sbuf_delete(sqlcond);
			return (EX_USAGE);
		}
		sbuf_finish(sqlcond);
	}

	ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);
	if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to query the package database");
		return (EX_NOPERM);
	} else if (ret == EPKG_ENODB) {
		if (!quiet)
			warnx("No packages installed");
		return (EX_OK);
	} else if (ret != EPKG_OK)
		return (EX_IOERR);

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get a read lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (match == MATCH_ALL || match == MATCH_CONDITION) {
		const char *condition_sql = NULL;
		if (match == MATCH_CONDITION && sqlcond)
			condition_sql = sbuf_data(sqlcond);
		if ((it = pkgdb_query(db, condition_sql, match)) == NULL)
			return (EX_IOERR);

		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK)
			print_query(pkg, argv[0],  multiline);

		if (ret != EPKG_END)
			retcode = EX_SOFTWARE;

		pkgdb_it_free(it);
	} else {
		int nprinted = 0;
		for (i = 1; i < argc; i++) {
			pkgname = argv[i];

			if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
				retcode = EX_IOERR;
				goto cleanup;
			}

			while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
				nprinted++;
				print_query(pkg, argv[0], multiline);
			}

			if (ret != EPKG_END) {
				retcode = EX_SOFTWARE;
				break;
			}

			pkgdb_it_free(it);
		}
		if (nprinted == 0 && retcode == EX_OK) {
			/* ensure to return a non-zero status when no package
			 were found. */
			retcode = EX_UNAVAILABLE;
		}
	}

cleanup:
	pkg_free(pkg);

	pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
	pkgdb_close(db);

	return (retcode);
}
Пример #29
0
Файл: lock.c Проект: jillest/pkg
static int
exec_lock_unlock(int argc, char **argv, enum action action)
{
	struct pkgdb	*db = NULL;
	struct pkgdb_it	*it = NULL;
	struct pkg	*pkg = NULL;
	const char	*pkgname;
	int		 match = MATCH_EXACT;
	int		 retcode;
	int		 exitcode = EX_OK;
	int		 ch;
	bool		 show_locked = false;

	struct option longopts[] = {
		{ "all",		no_argument,	NULL,	'a' },
		{ "case-sensitive",	no_argument,	NULL,	'C' },
		{ "glob",		no_argument,	NULL,	'g' },
		{ "show-locked",	no_argument,	NULL,	'l' },
		{ "quiet",		no_argument,	NULL,	'q' },
		{ "regex",		no_argument,	NULL,	'x' },
		{ "yes",		no_argument,	NULL,	'y' },
		{ NULL,		0,			NULL,	0   },
	};

	while ((ch = getopt_long(argc, argv, "aCgilqxy", longopts, NULL)) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'C':
			pkgdb_set_case_sensitivity(true);
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'l':
			show_locked = true;
			break;
		case 'q':
			quiet = true;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_lock();
			return (EX_USAGE);
		}
        }
	argc -= optind;
	argv += optind;

	

	if (!(match == MATCH_ALL && argc == 0) && argc != 1 && !show_locked) {
		usage_lock();
		return (EX_USAGE);
	}

	if (match == MATCH_ALL)
		pkgname = NULL;
	else
		pkgname = argv[0];

	retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
			       PKGDB_DB_LOCAL);
	if (retcode == EPKG_ENODB) {
		if (match == MATCH_ALL)
			return (EX_OK);
		if (!quiet)
			warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (retcode == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to modify the package database");
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	retcode = pkgdb_open(&db, PKGDB_DEFAULT);
	if (retcode != EPKG_OK)
		return (EX_IOERR);

	if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get an exclusive lock on database. "
		      "It is locked by another process");
		return (EX_TEMPFAIL);
	}

	if (match == MATCH_ALL || argc != 0) {
		if ((it = pkgdb_query(db, pkgname, match)) == NULL) {
			exitcode = EX_IOERR;
			goto cleanup;
		}

		while ((retcode = pkgdb_it_next(it, &pkg, 0)) == EPKG_OK) {
			if (action == LOCK)
				retcode = do_lock(db, pkg);
			else
				retcode = do_unlock(db, pkg);

			if (retcode != EPKG_OK) {
				exitcode = EX_IOERR;
				goto cleanup;
			}
		}
	}

	if (show_locked) 
		retcode = list_locked(db);

	if (retcode != EPKG_END)
		exitcode = EX_IOERR;

cleanup:
	if (pkg != NULL)
		pkg_free(pkg);
	if (it != NULL)
		pkgdb_it_free(it);

	pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
	pkgdb_close(db);

	return (exitcode);
}
Пример #30
0
/*
 * add1pkg(<pkg>)
 *	adds the files listed in the +CONTENTS of <pkg> into the
 *	pkgdb.byfile.db database file in the current package dbdir.  It
 *	returns the number of files added to the database file.
 */
static int
add_pkg(const char *pkgdir, void *vp)
{
    FILE	       *f;
    plist_t	       *p;
    package_t	Plist;
    char 	       *contents;
    char *PkgName, *dirp;
    char 		file[MaxPathSize];
    struct pkgdb_count *count;

    if (!pkgdb_open(ReadWrite))
        err(EXIT_FAILURE, "cannot open pkgdb");

    count = vp;
    ++count->packages;

    contents = pkgdb_pkg_file(pkgdir, CONTENTS_FNAME);
    if ((f = fopen(contents, "r")) == NULL)
        errx(EXIT_FAILURE, "%s: can't open `%s'", pkgdir, CONTENTS_FNAME);
    free(contents);

    read_plist(&Plist, f);
    if ((p = find_plist(&Plist, PLIST_NAME)) == NULL) {
        errx(EXIT_FAILURE, "Package `%s' has no @name, aborting.", pkgdir);
    }

    PkgName = p->name;
    dirp = NULL;
    for (p = Plist.head; p; p = p->next) {
        switch(p->type) {
        case PLIST_FILE:
            if (dirp == NULL) {
                errx(EXIT_FAILURE, "@cwd not yet found, please send-pr!");
            }
            (void) snprintf(file, sizeof(file), "%s/%s", dirp, p->name);
            if (!(isfile(file) || islinktodir(file))) {
                if (isbrokenlink(file)) {
                    warnx("%s: Symlink `%s' exists and is in %s but target does not exist!",
                          PkgName, file, CONTENTS_FNAME);
                } else {
                    warnx("%s: File `%s' is in %s but not on filesystem!",
                          PkgName, file, CONTENTS_FNAME);
                }
            } else {
                pkgdb_store(file, PkgName);
                ++count->files;
            }
            break;
        case PLIST_PKGDIR:
            add_pkgdir(PkgName, dirp, p->name);
            ++count->directories;
            break;
        case PLIST_CWD:
            if (strcmp(p->name, ".") != 0)
                dirp = p->name;
            else
                dirp = pkgdb_pkg_dir(pkgdir);
            break;
        case PLIST_IGNORE:
            p = p->next;
            break;
        case PLIST_SHOW_ALL:
        case PLIST_SRC:
        case PLIST_CMD:
        case PLIST_CHMOD:
        case PLIST_CHOWN:
        case PLIST_CHGRP:
        case PLIST_COMMENT:
        case PLIST_NAME:
        case PLIST_UNEXEC:
        case PLIST_DISPLAY:
        case PLIST_PKGDEP:
        case PLIST_DIR_RM:
        case PLIST_OPTION:
        case PLIST_PKGCFL:
        case PLIST_BLDDEP:
            break;
        }
    }
    free_plist(&Plist);
    fclose(f);
    pkgdb_close();

    return 0;
}