Esempio n. 1
0
int version_constraints_satisfied(depend_t * depends, pkg_t * pkg)
{
    pkg_t *temp;
    int comparison;

    if (depends->constraint == NONE)
        return 1;

    temp = pkg_new();

    parse_version(temp, depends->version);

    comparison = pkg_compare_versions(pkg, temp);

    free(temp->version);
    free(temp);

    if ((depends->constraint == EARLIER) && (comparison < 0))
        return 1;
    else if ((depends->constraint == LATER) && (comparison > 0))
        return 1;
    else if ((depends->constraint == EQUAL) && (comparison == 0))
        return 1;
    else if ((depends->constraint == LATER_EQUAL) && (comparison >= 0))
        return 1;
    else if ((depends->constraint == EARLIER_EQUAL) && (comparison <= 0))
        return 1;

    return 0;
}
Esempio n. 2
0
static tn_array *parse_removed(char *str) 
{
    char *p, *q;
    tn_array *pkgs;

    pkgs = pkgs_array_new(64);
    p = q = eatws(str);
    while ((p = next_tokn(&q, ' ', NULL)) != NULL) {
        const char   *name = NULL, *ver = NULL, *rel = NULL;
        int32_t      epoch = 0;
        struct pkg  *pkg;

        if (*p == '\0')
            continue;
        
        if ((pkg = pndir_parse_pkgkey(p, strlen(p), NULL)) == NULL) {
            if (poldek_util_parse_nevr(p, &name, &epoch, &ver, &rel)) {
                pkg = pkg_new(name, epoch, ver, rel, NULL, NULL);
            }
        }
        
        if (pkg)
            n_array_push(pkgs, pkg);
    }
    
    if (n_array_size(pkgs) == 0) {
        n_array_free(pkgs);
        pkgs = NULL;
    }
    
    return pkgs;
}
Esempio n. 3
0
static int do_test_pkgmatch(char *capevr, char *evr, int relation, unsigned maflags,
                     int expected) 
{
    struct pkg *pkg;
    struct capreq *req;
    const char *ver, *rel;
    int rc;
    int32_t epoch;

    if (!poldek_util_parse_evr(n_strdup(capevr), &epoch, &ver, &rel))
        return -1;
    
    pkg = pkg_new("poo", epoch, ver, rel,  NULL, NULL);
    req = capreq_new_evr(NULL, "poo", n_strdup(evr), relation, 0);

    rc = pkg_xmatch_req(pkg, req, maflags) ? 1 : 0;
    msgn_i(1, 2, "%s match%s %s => %s", pkg_evr_snprintf_s(pkg),
           maflags_snprintf_s(maflags), capreq_snprintf_s(req),
           rc ? "YES" : "NO");

    fail_if(rc != expected,
            "match %s <=> %s not equal %d",
            pkg_evr_snprintf_s(pkg), capreq_snprintf_s(req), expected);
    pkg_free(pkg);
    capreq_free(req);
    return rc;
}
Esempio n. 4
0
File: update.c Progetto: zxombie/pkg
static int
pkg_repo_binary_add_from_manifest(char *buf, const char *origin, const char *digest,
		long offset, sqlite3 *sqlite,
		struct pkg_manifest_key **keys, struct pkg **p, bool is_legacy,
		struct pkg_repo *repo)
{
	int rc = EPKG_OK;
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

	if (*p == NULL) {
		rc = pkg_new(p, PKG_REMOTE);
		if (rc != EPKG_OK)
			return (EPKG_FATAL);
	} else {
		pkg_reset(*p, PKG_REMOTE);
	}

	pkg = *p;

	pkg_manifest_keys_new(keys);
	rc = pkg_parse_manifest(pkg, buf, offset, *keys);
	if (rc != EPKG_OK) {
		goto cleanup;
	}
	rc = pkg_is_valid(pkg);
	if (rc != EPKG_OK) {
		goto cleanup;
	}

	/* Ensure that we have a proper origin and arch*/
	pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch);
	if (local_origin == NULL || strcmp(local_origin, origin) != 0) {
		pkg_emit_error("manifest contains origin %s while we wanted to add origin %s",
				local_origin ? local_origin : "NULL", origin);
		rc = EPKG_FATAL;
		goto cleanup;
	}

	if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) {
		rc = EPKG_FATAL;
		pkg_emit_error("repository %s contains packages with wrong ABI: %s",
			repo->name, pkg_arch);
		goto cleanup;
	}

	pkg_set(pkg, PKG_REPONAME, repo->name);
	if (is_legacy) {
		pkg_set(pkg, PKG_OLD_DIGEST, digest);
		pkg_checksum_calculate(pkg, NULL);
	}
	else {
		pkg_set(pkg, PKG_DIGEST, digest);
	}

	rc = pkg_repo_binary_add_pkg(pkg, NULL, sqlite, true);

cleanup:
	return (rc);
}
Esempio n. 5
0
/**
 * @brief Creates a new FreeBSD package from one installed on a system
 * @param pkg_name The name of the package to retrieve
 * @param pkg_db_dir The directory in the database the package is registered in
 * @todo Make this work through a pkg_db callback
 * @todo Remove the need for pkg_db_dir by using a struct pkg_repo
 * @todo move the freebsd_package creation to an internal function
 *
 * This creates a package object from an installed package.
 * It can be used to retrieve information from the pkg_db and deintall
 * the package.
 * @return A pkg object or NULL
 */
struct pkg *
pkg_new_freebsd_installed(const char *pkg_name, const char *pkg_db_dir)
{
	struct pkg *pkg;
	struct freebsd_package *fpkg;
	struct stat sb;

	/* check the directory exists and is a directory */
	if (lstat(pkg_db_dir, &sb) == -1)
		return NULL;
	if (!S_ISDIR(sb.st_mode))
		return NULL;

	pkg = pkg_new(pkg_name, freebsd_get_control_files,
	    freebsd_get_control_file, NULL, freebsd_free);
	if (pkg == NULL)
		return NULL;
	pkg_add_callbacks_data(pkg, freebsd_get_version, freebsd_get_origin);

	fpkg = freebsd_package_new();
	if (fpkg == NULL) {
		pkg_free(pkg);
		return NULL;
	}
	pkg->data = fpkg;

	fpkg->pkg_type = fpkg_from_installed;

	fpkg->db_dir = strdup(pkg_db_dir);
	if (fpkg->db_dir == NULL) {
		pkg_free(pkg);
		return NULL;
	}
	return pkg;
}
Esempio n. 6
0
static int
pkg_read_manifest_v2(FILE *fs, struct pkg **pkg_p, struct pkg_manifest_key *keys)
{
	struct pkg_section_hdr sec;
	struct pkg *pkg;
	void *payload;
	size_t paylen;
	int retcode = EPKG_OK;

	if (pkg_skip_to_section(fs, PKG_FORMAT_SECTION_MANIFEST, &sec) != EPKG_OK) {
		return (EPKG_FATAL);
	}

	if (pkg_section_maybe_uncompress(fs, &sec, &payload, &paylen) != EPKG_OK) {
		return (EPKG_FATAL);
	}

	retcode = pkg_new(pkg_p, PKG_FILE);
	if (retcode != EPKG_OK) {
		goto cleanup;
	}

	pkg = *pkg_p;
	retcode = pkg_parse_manifest(pkg, payload, paylen, keys);

cleanup:
	free(payload);

	return (retcode);
}
Esempio n. 7
0
File: update.c Progetto: renchap/pkg
static int
pkg_add_from_manifest(FILE *f, char *buf, const char *origin, long offset,
		const char *manifest_digest, const char *local_arch, sqlite3 *sqlite,
		struct pkg_manifest_parser **parser, struct pkg **p)
{
	int rc = EPKG_OK;
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

	if (buf == NULL && fseek(f, offset, SEEK_SET) == -1) {
		pkg_emit_errno("fseek", "invalid manifest offset");
		return (EPKG_FATAL);
	}

	if (*p == NULL) {
		rc = pkg_new(p, PKG_REMOTE);
		if (rc != EPKG_OK)
			return (EPKG_FATAL);
	} else {
		pkg_reset(*p, PKG_REMOTE);
	}

	pkg = *p;

	pkg_manifest_parser_new(parser);
	if (buf == NULL) {
		rc = pkg_parse_manifest_file_ev(pkg, f, *parser);
	} else {
		rc = pkg_parse_manifest_ev(pkg, buf, offset, *parser);
	}
	if (rc != EPKG_OK) {
		goto cleanup;
	}
	rc = pkg_is_valid(pkg);
	if (rc != EPKG_OK) {
		goto cleanup;
	}

	/* Ensure that we have a proper origin and arch*/
	pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch);
	if (local_origin == NULL || strcmp(local_origin, origin) != 0) {
		pkg_emit_error("manifest contains origin %s while we wanted to add origin %s",
				local_origin ? local_origin : "NULL", origin);
		rc = EPKG_FATAL;
		goto cleanup;
	}
	if (pkg_arch == NULL || strcmp(pkg_arch, local_arch) != 0) {
		pkg_emit_error("package %s is built for %s arch, and local arch is %s",
				origin, pkg_arch ? pkg_arch : "NULL", local_arch);
		rc = EPKG_FATAL;
		goto cleanup;
	}

	rc = pkgdb_repo_add_package(pkg, NULL, sqlite, manifest_digest, true, false);

cleanup:
	return (rc);
}
Esempio n. 8
0
/*
 * Downloads file from url, installs in package database, return package name.
 */
int
opkg_prepare_url_for_install(const char *url, char **namep)
{
     int err = 0;
     pkg_t *pkg;

     pkg = pkg_new();

     if (str_starts_with(url, "http://")
	 || str_starts_with(url, "ftp://")) {
	  char *tmp_file;
	  char *file_basec = xstrdup(url);
	  char *file_base = basename(file_basec);

	  sprintf_alloc(&tmp_file, "%s/%s", conf->tmp_dir, file_base);
	  err = opkg_download(url, tmp_file, NULL, NULL, 0);
	  if (err)
	       return err;

	  err = pkg_init_from_file(pkg, tmp_file);
	  if (err)
	       return err;

	  free(tmp_file);
	  free(file_basec);

     } else if (strcmp(&url[strlen(url) - 4], OPKG_PKG_EXTENSION) == 0
                || strcmp(&url[strlen(url) - 4], IPKG_PKG_EXTENSION) == 0
		|| strcmp(&url[strlen(url) - 4], DPKG_PKG_EXTENSION) == 0) {

	  err = pkg_init_from_file(pkg, url);
	  if (err)
	       return err;
	  opkg_msg(DEBUG2, "Package %s provided by hand (%s).\n",
		  pkg->name, pkg->local_filename);
          pkg->provided_by_hand = 1;

     } else {
       pkg_deinit(pkg);
       free(pkg);
       return 0;
     }

     pkg->dest = conf->default_dest;
     pkg->state_want = SW_INSTALL;
     pkg->state_flag |= SF_PREFER;
     hash_insert_pkg(pkg, 1);

     if (namep) {
	  *namep = pkg->name;
     }
     return 0;
}
Esempio n. 9
0
/* The "no concessions to old pkg_tools" variant: just get everything
 * from the manifest */
int
pkg_create_from_manifest(const char *outdir, pkg_formats format,
    const char *rootdir, const char *manifest, const char *plist)
{
	struct pkg	*pkg = NULL;
	struct packing	*pkg_archive = NULL;
	char		 arch[BUFSIZ];
	int		 ret = ENOMEM;
	struct pkg_manifest_key *keys = NULL;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	pkg_manifest_keys_new(&keys);
	if ((ret = pkg_parse_manifest_file(pkg, manifest, keys)) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if no arch autodetermine it */
	if (pkg->abi == NULL) {
		pkg_get_myarch(arch, BUFSIZ);
		pkg->abi = strdup(arch);
	}

	if (plist != NULL &&
	    ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	pkg_create_from_dir(pkg, rootdir, pkg_archive);
	ret = EPKG_OK;

cleanup:
	free(pkg);
	pkg_manifest_keys_free(keys);
	packing_finish(pkg_archive);

	return (ret);
}
Esempio n. 10
0
/**
 * @brief Creates a new FreeBSD package from a FILE pointer
 * @param fd A pointer to a FILE object containing a FreeBSD Package
 *
 * This creates a pkg object from a given file pointer.
 * It is able to then manipulate the package and install the it to the pkg_db.
 * @todo Write
 * @return A new package object or NULL
 */
struct pkg *
pkg_new_freebsd_from_file(FILE *fd)
{
	struct pkg *pkg;
	struct freebsd_package *fpkg;
	const char *pkg_name;

	if (fd == NULL)
		return NULL;

	/* Create the new package data object */
	fpkg = freebsd_package_new();
	if (fpkg == NULL)
		return NULL;

	fpkg->fd = fd;
	fpkg->pkg_type = fpkg_from_file;
	fpkg->archive = archive_read_new();
	archive_read_support_compression_bzip2(fpkg->archive);
	archive_read_support_compression_gzip(fpkg->archive);
	archive_read_support_format_tar(fpkg->archive);
	archive_read_open_stream(fpkg->archive, fd, 10240);
	
	/*
	 * Get the +CONTENTS file.
	 * We can't use the callbacks as we need the
	 * package name to use with pkg_new
	 */
	freebsd_open_control_files(fpkg);
	assert(fpkg->control != NULL);

	freebsd_parse_contents(fpkg);
	assert(fpkg->contents != NULL);
	if (fpkg->contents->lines[1].line_type != PKG_LINE_NAME) {
		/** @todo cleanup */
		return NULL;
	}

	pkg_name = fpkg->contents->lines[1].data;
	pkg = pkg_new(pkg_name, freebsd_get_control_files,
	    freebsd_get_control_file, freebsd_get_deps, freebsd_free);
	if (pkg == NULL) {
		/** @todo cleanup */
		return NULL;
	}
	pkg_add_callbacks_data(pkg, freebsd_get_version, freebsd_get_origin);
	pkg_add_callbacks_install(pkg, freebsd_get_next_file,
	    freebsd_run_script);
	pkg->data = fpkg;

	return pkg;
}
Esempio n. 11
0
Pkg *pkg_db_get_installed_matched(PkgDb db, const char *pattern){
	Pkg *pkgs;
	struct dirent *dirn;
	size_t size;
	int count = 0;
	
	if(db == NULL || db->db_d == NULL || db->d_h == NULL)
		RETURN_P_ERR(P_ERR_INVALID_DESCRIPTOR, NULL);

	size = sizeof(Pkg);
	pkgs = malloc(size);
	assert(pkgs != NULL);
	pkgs[0] = NULL;

	while((dirn = readdir(db->d_h)) != NULL){
		if(pattern != NULL){
			if(!strncmp(pattern, dirn->d_name, strlen(pattern)) 
			&& dirn->d_type == DT_DIR
			&& dirn->d_name[0] != '.'){
				size += sizeof(Pkg);
				pkgs = reallocf(pkgs, size);
				assert(pkgs != NULL);
				pkgs[count++] = pkg_new(db->db_d, dirn->d_name);
				pkgs[count] = NULL;
			}
		}
		else if(dirn->d_type == DT_DIR && dirn->d_name[0] != '.'){
			size += sizeof(Pkg);
			pkgs = reallocf(pkgs, size);
			assert(pkgs != NULL);
			pkgs[count++] = pkg_new(db->db_d, dirn->d_name);
			pkgs[count] = NULL;
		}
	}

	return pkgs;
}
Esempio n. 12
0
/* The "no concessions to old pkg_tools" variant: just get everything
 * from the manifest */
int
pkg_create_from_manifest(const char *outdir, pkg_formats format,
			 const char *rootdir, const char *manifest, bool old)
{
	struct pkg	*pkg = NULL;
	struct packing	*pkg_archive = NULL;
	char		 arch[BUFSIZ];
	int		 ret = ENOMEM;
	char		*buf;
	struct pkg_manifest_key *keys = NULL;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	if(pkg_new(&pkg, old ? PKG_OLD_FILE : PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	pkg_manifest_keys_new(&keys);
	if ((ret = pkg_parse_manifest_file(pkg, manifest, keys)) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if no arch autodetermine it */
	pkg_get(pkg, PKG_ARCH, &buf);
	if (buf == NULL) {
		pkg_get_myarch(arch, BUFSIZ);
		pkg_set(pkg, PKG_ARCH, arch);
	}

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	pkg_create_from_dir(pkg, rootdir, pkg_archive);
	ret = EPKG_OK;

cleanup:
	free(pkg);
	pkg_manifest_keys_free(keys);
	if (ret == EPKG_OK)
		ret = packing_finish(pkg_archive);
	return (ret);
}
Esempio n. 13
0
static int
pkg_repo_add_from_manifest(char *buf, const char *origin, long offset,
		const char *manifest_digest, sqlite3 *sqlite,
		struct pkg_manifest_key **keys, struct pkg **p)
{
	int rc = EPKG_OK;
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

	if (*p == NULL) {
		rc = pkg_new(p, PKG_REMOTE);
		if (rc != EPKG_OK)
			return (EPKG_FATAL);
	} else {
		pkg_reset(*p, PKG_REMOTE);
	}

	pkg = *p;

	pkg_manifest_keys_new(keys);
	rc = pkg_parse_manifest(pkg, buf, offset, *keys);
	if (rc != EPKG_OK) {
		goto cleanup;
	}
	rc = pkg_is_valid(pkg);
	if (rc != EPKG_OK) {
		goto cleanup;
	}

	/* Ensure that we have a proper origin and arch*/
	pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch);
	if (local_origin == NULL || strcmp(local_origin, origin) != 0) {
		pkg_emit_error("manifest contains origin %s while we wanted to add origin %s",
				local_origin ? local_origin : "NULL", origin);
		rc = EPKG_FATAL;
		goto cleanup;
	}

	if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) {
		rc = EPKG_FATAL;
		goto cleanup;
	}

	rc = pkgdb_repo_add_package(pkg, NULL, sqlite, manifest_digest, true);

cleanup:
	return (rc);
}
Esempio n. 14
0
int
pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
    const char *md_dir, char *plist)
{
	struct pkg	*pkg = NULL;
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	struct packing	*pkg_archive = NULL;
	int		 ret = EPKG_FATAL;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	if ((ret = pkg_new(&pkg, PKG_FILE)) != EPKG_OK)
		goto cleanup;

	if ((ret = pkg_load_metadata(pkg, NULL, md_dir, plist, rootdir, false))
	    != EPKG_OK)
		goto cleanup;

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	/* XXX: autoplist support doesn't work right with meta-ports */
	if (0 && pkg_files(pkg, &file) != EPKG_OK &&
	    pkg_dirs(pkg, &dir) != EPKG_OK) {
		/* Now traverse the file directories, adding to the archive */
		packing_append_tree(pkg_archive, md_dir, NULL);
		packing_append_tree(pkg_archive, rootdir, "/");
		ret = EPKG_OK;
	} else {
		ret = pkg_create_from_dir(pkg, rootdir, pkg_archive);
	}

cleanup:
	free(pkg);
	packing_finish(pkg_archive);
	return (ret);
}
Esempio n. 15
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);
}
Esempio n. 16
0
int
pkg_create_fakeroot(const char *outdir, pkg_formats format, const char *rootdir, const char *metadatadir)
{
	struct pkg *pkg = NULL;
	struct packing *pkg_archive = NULL;
	char *manifest = NULL, *manifest_path = NULL;
	int ret = ENOMEM;

	/* Load the manifest from the metadata directory */
	if (asprintf(&manifest_path, "%s/+MANIFEST", metadatadir) == -1)
		goto cleanup;

	pkg_new(&pkg, PKG_FILE);
	if (pkg == NULL)
		goto cleanup;

	ret = pkg_load_manifest_file(pkg, manifest_path);

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	/* Now traverse the file directories, adding to the archive */
	packing_append_tree(pkg_archive, metadatadir, NULL);
	packing_append_tree(pkg_archive, rootdir, "/");
	ret = EPKG_OK;

cleanup:
	if (pkg != NULL)
		free(pkg);
	if (manifest_path != NULL)
		free(manifest_path);
	if (manifest != NULL)
		free(manifest);
	if (ret == EPKG_OK)
		ret = packing_finish(pkg_archive);
	return ret;
}
Esempio n. 17
0
File: pkg_hash.c Progetto: DgINC/USP
int pkg_hash_add_from_file(ipkg_conf_t *conf, const char *file_name,
			   pkg_src_t *src, pkg_dest_t *dest, int is_status_file)
{
     hash_table_t *hash = &conf->pkg_hash;
     char **raw;
     char **raw_start;
     pkg_t *pkg;
    
     raw = raw_start = read_raw_pkgs_from_file(file_name);
     if (!raw)
        return -ENOMEM;

     while(*raw){         /* don't worry, we'll increment raw in the parsing function */
	  pkg = pkg_new();
	  if (!pkg)
	       return -ENOMEM;

	  if (pkg_parse_raw(pkg, &raw, src, dest) == 0) {
	       if (!pkg->architecture) {
		    char *version_str = pkg_version_str_alloc(pkg);
		    pkg->architecture = pkg_get_default_arch(conf);
		    ipkg_message(conf, IPKG_ERROR, "Package %s version %s has no architecture specified, defaulting to %s.\n",
				 pkg->name, version_str, pkg->architecture);
		    free(version_str);
	       }
	       hash_insert_pkg(hash, pkg, is_status_file,conf);
	  } else {
	       free(pkg);
	  }
     }

     /* XXX: CLEANUP: I'd like a cleaner interface for cleaning up
	memory after read_raw_pkgs_from_file */
     raw = raw_start;
     while (*raw) {
	  free(*raw++);
     }
     free(raw_start);
     return 0;
}
Esempio n. 18
0
struct pkg *
pkg_new_freebsd(FILE *fd)
{
	struct pkg *pkg;
	struct freebsd_package *f_pkg;
	char *pkg_name;

	f_pkg = freebsd_get_package(fd);

	/* Find the package name */
	pkg_name = freebsd_get_pkg_name(f_pkg->control[0]->contents);

	pkg = pkg_new(pkg_name, freebsd_get_control_files,
		freebsd_get_next_file, freebsd_get_deps, freebsd_free);
	free(pkg_name);

	if (pkg == NULL)
		return NULL;

	pkg->data = f_pkg;

	return pkg;
}
Esempio n. 19
0
/* The "no concessions to old pkg_tools" variant: just get everything
 * from the manifest */
int
pkg_create_from_manifest(const char *outdir, pkg_formats format,
    const char *rootdir, const char *manifest, const char *plist)
{
	struct pkg	*pkg = NULL;
	struct packing	*pkg_archive = NULL;
	int		 ret = ENOMEM;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	if ((ret = pkg_load_metadata(pkg, manifest, NULL, plist, rootdir, false))
	    != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	if ((ret = pkg_create_from_dir(pkg, rootdir, pkg_archive)) != EPKG_OK)
		pkg_emit_error("package creation failed");

cleanup:
	free(pkg);
	packing_finish(pkg_archive);
	return (ret);
}
Esempio n. 20
0
File: register.c Progetto: flz/pkgng
int
exec_register(int argc, char **argv)
{
	struct pkg *pkg;
	struct pkgdb *db;
	struct utsname u;

	regex_t preg;
	regmatch_t pmatch[2];

	int ch;
	char *plist = NULL;
	char *v = NULL;
	char *arch = NULL;
	char *mdir = NULL;
	char *www = NULL;
	char *input_path = NULL;
	char fpath[MAXPATHLEN];

	const char *desc = NULL;
	size_t size;

	bool heuristic = false;
	bool legacy = false;

	int retcode = 0;
	int ret = 0;

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

	pkg_new(&pkg, PKG_INSTALLED);
	while ((ch = getopt(argc, argv, "a:f:m:i:l")) != -1) {
		switch (ch) {
			case 'f':
				if ((plist = strdup(optarg)) == NULL)
					errx(1, "cannot allocate memory");

				break;
			case 'm':
				mdir = strdup(optarg);
				break;
			case 'a':
				arch = strdup(optarg);
				break;
			case 'i':
				if ((input_path = strdup(optarg)) == NULL)
					errx(1, "cannot allocate memory");
				break;
			case 'l':
				legacy = true;
				break;
			default:
				printf("%c\n", ch);
				usage_register();
				return (-1);
		}
	}

	if (ret != 0) {
		pkg_error_warn("can not parse arguments");
		return (1);
	}

	if (plist == NULL)
		errx(EX_USAGE, "missing -f flag");

	uname(&u);
	if (arch == NULL) {
		pkg_set(pkg, PKG_ARCH, u.machine);
	} else {
		pkg_set(pkg, PKG_ARCH, arch);
		free(arch);
	}

	if (mdir == NULL)
		errx(EX_USAGE, "missing -m flag");

	snprintf(fpath, MAXPATHLEN, "%s/+MANIFEST", mdir);
	if ((ret = pkg_load_manifest_file(pkg, fpath)) != EPKG_OK) {
		pkg_error_warn("can not parse manifest %s", fpath);
		return (EX_SOFTWARE);
	}

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

	snprintf(fpath, MAXPATHLEN, "%s/+DISPLAY", mdir);
	pkg_set_from_file(pkg, PKG_MESSAGE, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+MTREE_DIR", mdir);
	pkg_set_from_file(pkg, PKG_MTREE, mdir);

	snprintf(fpath, MAXPATHLEN, "%s/+INSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+PRE_INSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+POST_INSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+DEINSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+PRE_DEINSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+POST_DEINSTALL", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+UPGRADE", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+PRE_UPGRADE", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/+POST_UPGRADE", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-install", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-install", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-post-install", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-deinstall", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-post-deinstall", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-upgrade", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-pre-deupgrade", mdir);
	pkg_addscript(pkg, fpath);

	snprintf(fpath, MAXPATHLEN, "%s/pkg-post-deupgrade", mdir);
	pkg_addscript(pkg, fpath);

	/* if www is not given then try to determine it from description */
	if (www == NULL) {
		desc = pkg_get(pkg, PKG_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);
	} else {
		pkg_set(pkg, PKG_WWW, www);
		free(www);
	}

	if (strstr(u.release, "RELEASE") == NULL) {
		asprintf(&v, "%s-%d", u.release, __FreeBSD_version);
		pkg_set(pkg, PKG_OSVERSION, v);
		free(v);
	} else {
		pkg_set(pkg, PKG_OSVERSION, u.release);
	}
	/* TODO: missing osversion get it from uname*/

	ret += ports_parse_plist(pkg, plist);

	if (ret != 0) {
		pkg_error_warn("can not parse plist file");
		return (-1);
	}

	if (plist != NULL)
		free(plist);

	if (pkgdb_open(&db, PKGDB_DEFAULT, R_OK|W_OK) != EPKG_OK) {
		pkg_error_warn("can not open database");
		return (-1);
	}

	if (heuristic)
		pkg_analyse_files(db, pkg);

	if (input_path != NULL) {
		pkg_copy_tree(pkg, input_path, "/");
		free(input_path);
	}

	if (pkgdb_register_pkg(db, pkg) != EPKG_OK) {
		pkg_error_warn("can not register package");
		retcode = 1;
	}

	pkgdb_register_finale(db, ret);
	if (ret != EPKG_OK) {
		pkg_error_warn("can not register package");
		retcode = 1;
	}

	if (pkg_get(pkg, PKG_MESSAGE) != NULL && !legacy)
		printf("%s\n", pkg_get(pkg, PKG_MESSAGE));

	pkgdb_close(db);
	pkg_free(pkg);

	return (retcode);
}
Esempio n. 21
0
int
pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
    const char *md_dir, char *plist, bool old)
{
	struct pkg	*pkg = NULL;
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	struct packing	*pkg_archive = NULL;
	char		*manifest = NULL;
	char		 path[MAXPATHLEN];
	char		 arch[BUFSIZ];
	int		 ret = ENOMEM;
	char		*buf;
	int		 i;
	regex_t		 preg;
	regmatch_t	 pmatch[2];
	size_t		 size;
	char		*www = NULL;
	struct pkg_manifest_key *keys = NULL;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	/* Load the manifest from the metadata directory */
	if (snprintf(path, sizeof(path), "%s/+MANIFEST", md_dir) == -1)
		goto cleanup;

	if(pkg_new(&pkg, old ? PKG_OLD_FILE : PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	pkg_manifest_keys_new(&keys);
	if ((ret = pkg_parse_manifest_file(pkg, path, keys)) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if no descriptions provided then try to get it from a file */

	pkg_get(pkg, PKG_DESC, &buf);
	if (buf == NULL) {
		if (snprintf(path, sizeof(path), "%s/+DESC", md_dir) == -1)
			goto cleanup;
		if (access(path, F_OK) == 0) {
			pkg_debug(1, "Taking description from: '%s'", path);
			pkg_set_from_file(pkg, PKG_DESC, path, false);
		}
	}

	/* if no message try to get it from a file */
	pkg_get(pkg, PKG_MESSAGE, &buf);
	if (buf == NULL) {
		ret = snprintf(path, sizeof(path), "%s/+DISPLAY", md_dir);
		if (ret == -1)
			goto cleanup;
		if (access(path, F_OK) == 0) {
			pkg_debug(1, "Taking message from: '%s'", path);
			pkg_set_from_file(pkg, PKG_MESSAGE, path, false);
		}
	}

	/* if no arch autodetermine it */
	pkg_get(pkg, PKG_ARCH, &buf);
	if (buf == NULL) {
		pkg_get_myarch(arch, BUFSIZ);
		pkg_set(pkg, PKG_ARCH, arch);
	}

	/* if no mtree try to get it from a file */
	pkg_get(pkg, PKG_MTREE, &buf);
	if (buf == NULL) {
		ret = snprintf(path, sizeof(path), "%s/+MTREE_DIRS", md_dir);
		if (ret == -1)
			goto cleanup;
		if (access(path, F_OK) == 0) {
			pkg_debug(1, "Taking mtree definition from: '%s'", path);
			pkg_set_from_file(pkg, PKG_MTREE, path, false);
		}
	}

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

	if (plist != NULL &&
	    ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if www is not given then try to determine it from description */
	if (www != NULL) {
		pkg_set(pkg, PKG_WWW, www);
		free(www);
	}

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

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	/* XXX: autoplist support doesn't work right with meta-ports */
	if (0 && pkg_files(pkg, &file) != EPKG_OK &&
	    pkg_dirs(pkg, &dir) != EPKG_OK) {
		/* Now traverse the file directories, adding to the archive */
		packing_append_tree(pkg_archive, md_dir, NULL);
		packing_append_tree(pkg_archive, rootdir, "/");
	} else {
		pkg_create_from_dir(pkg, rootdir, pkg_archive);
	}

	ret = EPKG_OK;

cleanup:
	free(pkg);
	free(manifest);
	pkg_manifest_keys_free(keys);
	if (ret == EPKG_OK)
		ret = packing_finish(pkg_archive);
	return ret;
}
Esempio n. 22
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);
*/
}
Esempio n. 23
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);
*/
}
Esempio n. 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);
}
Esempio n. 25
0
int
exec_register(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb *db = NULL;

	regex_t preg;
	regmatch_t pmatch[2];

	int ch;
	char *plist = NULL;
	char *arch = NULL;
	char myarch[BUFSIZ];
	char *mdir = NULL;
	char *www = NULL;
	char *input_path = NULL;
	char fpath[MAXPATHLEN + 1];

	const char *message;
	const char *desc = NULL;
	size_t size;

	bool legacy = false;
	bool developer = false;

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

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

	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);

	pkg_new(&pkg, PKG_INSTALLED);
	while ((ch = getopt(argc, argv, "f:m:i:ld")) != -1) {
		switch (ch) {
		case 'f':
			if ((plist = strdup(optarg)) == NULL)
				err(1, "cannot allocate memory");

			break;
		case 'm':
			if ((mdir = strdup(optarg)) == NULL)
				err(1, "cannot allocate memory");
			break;
		case 'd':
			pkg_set(pkg, PKG_AUTOMATIC, true);
			break;
		case 'i':
			if ((input_path = strdup(optarg)) == NULL)
				err(1, "cannot allocate memory");
			break;
		case 'l':
			legacy = true;
			break;
		default:
			printf("%c\n", ch);
			usage_register();
			return (EX_USAGE);
		}
	}

	if (plist == NULL)
		errx(EX_USAGE, "missing -f flag");

	if (mdir == NULL)
		errx(EX_USAGE, "missing -m flag");

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

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

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

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

	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 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);
	} else {
		pkg_set(pkg, PKG_WWW, www);
		free(www);
	}

	ret += ports_parse_plist(pkg, plist, input_path);

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

	if (plist != NULL)
		free(plist);

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

	pkg_analyse_files(db, pkg);

	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 (input_path != NULL) {
		pkg_copy_tree(pkg, input_path, "/");
		free(input_path);
	}

	if (pkgdb_register_ports(db, pkg) != EPKG_OK)
		retcode = EX_SOFTWARE;

	pkg_get(pkg, PKG_MESSAGE, &message);
	if (message != NULL && !legacy)
		printf("%s\n", message);

	pkgdb_close(db);
	pkg_free(pkg);

	return (retcode);
}
Esempio n. 26
0
ATF_TC_BODY(parse_plist, tc)
{
	struct pkg *p;
	struct plist *plist;
	char buf[BUFSIZ];

	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_INSTALLED));

	plist = plist_new(p, "/plop");
	ATF_REQUIRE(plist != NULL);
	ATF_REQUIRE(plist->pkg == p);
	ATF_REQUIRE_EQ(plist->prefix[0], '\0');

	strlcpy(buf, "@cwd /myprefix", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(p->prefix, "/myprefix");

	ATF_REQUIRE_STREQ(plist->prefix, "/myprefix");

	ATF_REQUIRE_STREQ(plist->uname, "root");
	ATF_REQUIRE_STREQ(plist->gname, "wheel");

	strlcpy(buf, "@owner bob", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->uname, "bob");

	strlcpy(buf, "@group sponge", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->gname, "sponge");

	strlcpy(buf, "@group", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->gname, "wheel");

	strlcpy(buf, "@owner", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->uname, "root");

	strlcpy(buf, "@cwd plop", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->prefix, "plop");

	strlcpy(buf, "@cwd", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->prefix, "/myprefix");
	ATF_REQUIRE_STREQ(plist->slash, "/");

	strlcpy(buf, "@cwd /another/prefix/", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_STREQ(plist->prefix, "/another/prefix/");
	ATF_REQUIRE_STREQ(plist->slash, "");

	ATF_REQUIRE_EQ(0, plist->perm);
	strlcpy(buf, "@mode 0755", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_EQ(0755, plist->perm);

	strlcpy(buf, "@mode", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(p, plist, buf));
	ATF_REQUIRE_EQ(0, plist->perm);

	strlcpy(buf, "@blabla", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(p, plist, buf));

	strlcpy(buf, "nonexisting/file", BUFSIZ);
	ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(p, plist, buf));

	pkg_free(p);
	plist_free(plist);
}
Esempio n. 27
0
Pkg pkg_archive_get_pkg(char *a_path, PkgDb db){
	Pkg pkg;
	char *path;
	char *file,
	           *pkg_n;
	struct archive_entry *entry;
	struct archive *a;
	int r,
	    fd;
	
	if(a_path == NULL || db == NULL)
		RETURN_P_ERR(P_ERR_INVALID_DESCRIPTOR, NULL);
	
	pkg_n = pkg_archive_get_pkg_name(a_path);
	
	if(pkg_n == NULL)
		return NULL;
		
	asprintf(&path, "%s/%s", db->db_d, pkg_n);
	assert(path != NULL);
	
	r = mkdir(path, DEF_O_MODE);
	
	if(r == -1)
		if(errno != EEXIST && errno != EISDIR){
			free((void *)pkg_n);
			free(path);

			RETURN_P_ERRNO(NULL);
		}
	
	a = pkg_archive_open(a_path);
	
	if(a == NULL)
		return NULL;
	
	for(;;){
		r = archive_read_next_header(a, &entry);
		if(r == ARCHIVE_EOF)
			break;
		if(r != ARCHIVE_OK){
			free((void *)pkg_n);
			free(path);

			RETURN_P_LARCHIVE(NULL, a);
		}
			
		file = (char *)archive_entry_pathname(entry);
		
		if(file[0] == '+'){
			asprintf((void *)&file, "%s/%s", path, file);
			assert(file != NULL);
			
			fd = open(file, O_CREAT | O_WRONLY, DEF_O_MODE);
			
			if(fd == -1){
				pkg_archive_close(a);
				free((void *)pkg_n);
				free(path);
				free((void *)file);

				RETURN_P_ERRNO(NULL);
			}
			
			r = archive_read_data_into_fd(a, fd);
			
			close(fd);
			free((void *)file);
			
			if(r == -1){
				free((void *)pkg_n);
				free(path);

				RETURN_P_LARCHIVE(NULL, a);
			}
		}
	}
	
	pkg = pkg_new(db->db_d, pkg_n);
	
	pkg_archive_close(a);
	free((void *)pkg_n);
	free(path);
	
	return pkg;	
}
Esempio n. 28
0
int
pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
    const char *md_dir, char *plist)
{
	struct pkg	*pkg = NULL;
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	struct packing	*pkg_archive = NULL;
	char		*manifest = NULL;
	char		 arch[BUFSIZ];
	int		 ret = ENOMEM;
	int		 i, mfd;
	regex_t		 preg;
	regmatch_t	 pmatch[2];
	size_t		 size;
	struct pkg_manifest_key *keys = NULL;

	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);

	if ((mfd = open(md_dir, O_DIRECTORY)) == -1) {
		pkg_emit_errno("open", md_dir);
		goto cleanup;
	}

	if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	pkg_manifest_keys_new(&keys);
	/* Load the manifest from the metadata directory */
	if ((ret = pkg_parse_manifest_fileat(mfd, pkg, "+MANIFEST", keys))
	    != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	/* if no descriptions provided then try to get it from a file */
	if (pkg->desc == NULL)
		pkg_load_from_file(mfd, pkg, PKG_DESC, "+DESC");

	/* if no message try to get it from a file */
	if (pkg->message == NULL) {
		/* Try ucl version first */
		if (pkg_load_message_from_file(mfd, pkg, "+DISPLAY.ucl", true)
				!= EPKG_OK) {
			pkg_load_message_from_file(mfd, pkg, "+DISPLAY", false);
		}
	}

	/* if no arch autodetermine it */
	if (pkg->abi == NULL) {
		pkg_get_myarch(arch, BUFSIZ);
		pkg->abi = strdup(arch);
	}

	for (i = 0; scripts[i] != NULL; i++) {
		if (faccessat(mfd, scripts[i], F_OK, 0) == 0)
			pkg_addscript_fileat(mfd, pkg, scripts[i]);
	}

	if (plist != NULL &&
	    ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) {
		ret = EPKG_FATAL;
		goto cleanup;
	}

	if (pkg->www == NULL) {
		if (pkg->desc == NULL) {
			pkg_emit_error("No www or desc defined in manifest");
			ret = EPKG_FATAL;
			goto cleanup;
		}
		regcomp(&preg, "^WWW:[[:space:]]*(.*)$",
		    REG_EXTENDED|REG_ICASE|REG_NEWLINE);
		if (regexec(&preg, pkg->desc, 2, pmatch, 0) == 0) {
			size = pmatch[1].rm_eo - pmatch[1].rm_so;
			pkg->www = strndup(&pkg->desc[pmatch[1].rm_so], size);
		} else {
			pkg->www = strdup("UNKNOWN");
		}
		regfree(&preg);
	}

	/* Create the archive */
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
	if (pkg_archive == NULL) {
		ret = EPKG_FATAL; /* XXX do better */
		goto cleanup;
	}

	/* XXX: autoplist support doesn't work right with meta-ports */
	if (0 && pkg_files(pkg, &file) != EPKG_OK &&
	    pkg_dirs(pkg, &dir) != EPKG_OK) {
		/* Now traverse the file directories, adding to the archive */
		packing_append_tree(pkg_archive, md_dir, NULL);
		packing_append_tree(pkg_archive, rootdir, "/");
		ret = EPKG_OK;
	} else {
		ret = pkg_create_from_dir(pkg, rootdir, pkg_archive);
	}


cleanup:
	if (mfd != -1)
		close(mfd);
	free(pkg);
	free(manifest);
	pkg_manifest_keys_free(keys);
	packing_finish(pkg_archive);

	return (ret);
}
Esempio n. 29
0
/**
 * @brief Creates an empty package with no callbacks
 * @param pkg_name The name of the package
 *
 * This is the simplest package constructor.
 * It is used to create a package with just a name associated with it.
 * Only pkg_get_name() and pkg_compare() will work with the created package.
 * @return An empty package
 */
struct pkg*
pkg_new_empty(const char *pkg_name)
{
	return pkg_new(pkg_name, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
Esempio n. 30
0
int
exec_register(int argc, char **argv)
{
	struct pkg	*pkg = NULL;
	struct pkgdb	*db  = NULL;

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

	bool		 legacy        = false;
	bool		 testing_mode  = false;

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

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

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

	while ((ch = getopt_long(argc, argv, "+Adf:i:lM:m:t", 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':
			mfile = optarg;
			break;
		case 'm':
			mdir = optarg;
			break;
		case 't':
			testing_mode = true;
			break;
		case 1:
			location = optarg;
			break;
		default:
			warnx("Unrecognised option -%c\n", ch);
			usage_register();
			pkg_free(pkg);
			return (EX_USAGE);
		}
	}

	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");
		pkg_free(pkg);
		return (EX_NOPERM);
	} else if (retcode != EPKG_OK) {
		pkg_free(pkg);
		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();
		pkg_free(pkg);
		return (EX_USAGE);
	}


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

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

	ret = pkg_load_metadata(pkg, mfile, mdir, plist, input_path, testing_mode);
	if (ret != EPKG_OK) {
		pkg_free(pkg);
		return (EX_IOERR);
	}


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

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

	retcode = pkg_add_port(db, pkg, input_path, location, testing_mode);

	if (!legacy && retcode == EPKG_OK && messages != NULL) {
		printf("%s\n", utstring_body(messages));
	}

	pkg_free(pkg);

	return (retcode != EPKG_OK ? EX_SOFTWARE : EX_OK);
}