示例#1
0
static int
parse_mapping(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc, int attr)
{
	struct sbuf *tmp = NULL;
	yaml_node_pair_t *pair;
	yaml_node_t *key;
	yaml_node_t *val;
	pkg_script_t script_type;

	pair = item->data.mapping.pairs.start;
	while (pair < item->data.mapping.pairs.top) {
		key = yaml_document_get_node(doc, pair->key);
		val = yaml_document_get_node(doc, pair->value);

		if (key->data.scalar.length <= 0) {
			pkg_emit_error("Skipping empty dependency name");
			++pair;
			continue;
		}

		switch (attr) {
			case PKG_DEPS:
				if (val->type != YAML_MAPPING_NODE)
					pkg_emit_error("Skipping malformed depencency %s",
								   key->data.scalar.value);
				else
					pkg_set_deps_from_node(pkg, val, doc, key->data.scalar.value);
				break;
			case PKG_DIRS:
				if (val->type != YAML_MAPPING_NODE)
					pkg_emit_error("Skipping malformed dirs %s",
								   key->data.scalar.value);
				else
					pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value);
				break;
			case PKG_DIRECTORIES:
				if (val->type == YAML_SCALAR_NODE && val->data.scalar.length > 0) {
					urldecode(key->data.scalar.value, &tmp);
					if (val->data.scalar.value[0] == 'y')
						pkg_adddir(pkg, sbuf_data(tmp), 1);
					else
						pkg_adddir(pkg, sbuf_data(tmp), 0);
				} else if (val->type == YAML_MAPPING_NODE) {
					pkg_set_dirs_from_node(pkg, val, doc, key->data.scalar.value);
				} else {
					pkg_emit_error("Skipping malformed directories %s",
								   key->data.scalar.value);
				}
				break;
			case PKG_FILES:
				if (val->type == YAML_SCALAR_NODE && val->data.scalar.length > 0) {
					urldecode(key->data.scalar.value, &tmp);
					pkg_addfile(pkg, sbuf_data(tmp), val->data.scalar.length == 64 ? val->data.scalar.value : NULL);
				} else if (val->type == YAML_MAPPING_NODE)
					pkg_set_files_from_node(pkg, val, doc, key->data.scalar.value);
				else
					pkg_emit_error("Skipping malformed files %s",
								   key->data.scalar.value);
				break;
			case PKG_OPTIONS:
				if (val->type != YAML_SCALAR_NODE)
					pkg_emit_error("Skipping malformed option %s",
								   key->data.scalar.value);
				else
					pkg_addoption(pkg, key->data.scalar.value, val->data.scalar.value);
				break;
			case PKG_SCRIPTS:
				if (val->type != YAML_SCALAR_NODE)
					pkg_emit_error("Skipping malformed scripts %s",
								   key->data.scalar.value);
				if (strcmp(key->data.scalar.value, "pre-install") == 0) {
					script_type = PKG_SCRIPT_PRE_INSTALL;
				} else if (strcmp(key->data.scalar.value, "install") == 0) {
					script_type = PKG_SCRIPT_INSTALL;
				} else if (strcmp(key->data.scalar.value, "post-install") == 0) {
					script_type = PKG_SCRIPT_POST_INSTALL;
				} else if (strcmp(key->data.scalar.value, "pre-upgrade") == 0) {
					script_type = PKG_SCRIPT_PRE_UPGRADE;
				} else if (strcmp(key->data.scalar.value, "upgrade") == 0) {
					script_type = PKG_SCRIPT_UPGRADE;
				} else if (strcmp(key->data.scalar.value, "post-upgrade") == 0) {
					script_type = PKG_SCRIPT_POST_UPGRADE;
				} else if (strcmp(key->data.scalar.value, "pre-deinstall") == 0) {
					script_type = PKG_SCRIPT_PRE_DEINSTALL;
				} else if (strcmp(key->data.scalar.value, "deinstall") == 0) {
					script_type = PKG_SCRIPT_DEINSTALL;
				} else if (strcmp(key->data.scalar.value, "post-deinstall") == 0) {
					script_type = PKG_SCRIPT_POST_DEINSTALL;
				} else {
					pkg_emit_error("Skipping unknown script type: %s",
								   key->data.scalar.value);
					break;
				}

				pkg_addscript(pkg, val->data.scalar.value, script_type);
				break;
		}

		++pair;
	}

	sbuf_free(tmp);
	return (EPKG_OK);
}
示例#2
0
文件: register.c 项目: 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);
}
示例#3
0
文件: pkg_manifest.c 项目: grtodd/pkg
static int
pkg_object(struct pkg *pkg, ucl_object_t *obj, int attr)
{
	struct sbuf *tmp = NULL;
	ucl_object_t *cur;
	ucl_object_iter_t it = NULL;
	pkg_script script_type;
	const char *key, *buf;
	size_t len;

	pkg_debug(3, "%s", "Manifest: parsing object");
	while ((cur = ucl_iterate_object(obj, &it, true))) {
		key = ucl_object_key(cur);
		if (key == NULL)
			continue;
		switch (attr) {
		case PKG_DEPS:
			if (cur->type != UCL_OBJECT && cur->type != UCL_ARRAY)
				pkg_emit_error("Skipping malformed dependency %s",
				    key);
			else
				pkg_set_deps_from_object(pkg, cur);
			break;
		case PKG_DIRS:
			if (cur->type != UCL_OBJECT)
				pkg_emit_error("Skipping malformed dirs %s",
				    key);
			else
				pkg_set_dirs_from_object(pkg, cur);
			break;
		case PKG_USERS:
			if (cur->type == UCL_STRING)
				pkg_adduid(pkg, key, ucl_object_tostring(cur));
			else
				pkg_emit_error("Skipping malformed users %s",
				    key);
			break;
		case PKG_GROUPS:
			if (cur->type == UCL_STRING)
				pkg_addgid(pkg, key, ucl_object_tostring(cur));
			else
				pkg_emit_error("Skipping malformed groups %s",
				    key);
			break;
		case PKG_DIRECTORIES:
			if (cur->type == UCL_BOOLEAN) {
				urldecode(key, &tmp);
				pkg_adddir(pkg, sbuf_data(tmp), ucl_object_toboolean(cur), false);
			} else if (cur->type == UCL_OBJECT) {
				pkg_set_dirs_from_object(pkg, cur);
			} else if (cur->type == UCL_STRING) {
				urldecode(key, &tmp);
				if (ucl_object_tostring(cur)[0] == 'y')
					pkg_adddir(pkg, sbuf_data(tmp), 1, false);
				else
					pkg_adddir(pkg, sbuf_data(tmp), 0, false);
			} else {
				pkg_emit_error("Skipping malformed directories %s",
				    key);
			}
			break;
		case PKG_FILES:
			if (cur->type == UCL_STRING) {
				buf = ucl_object_tolstring(cur, &len);
				urldecode(key, &tmp);
				pkg_addfile(pkg, sbuf_get(tmp), len == 64 ? buf : NULL, false);
			} else if (cur->type == UCL_OBJECT)
				pkg_set_files_from_object(pkg, cur);
			else
				pkg_emit_error("Skipping malformed files %s",
				   key);
			break;
		case PKG_OPTIONS:
			if (cur->type != UCL_STRING && cur->type != UCL_BOOLEAN)
				pkg_emit_error("Skipping malformed option %s",
				    key);
			else
				pkg_addoption(pkg, key, ucl_object_tostring_forced(cur));
			break;
		case PKG_OPTION_DEFAULTS:
			if (cur->type != UCL_STRING)
				pkg_emit_error("Skipping malformed option default %s",
				    key);
			else
				pkg_addoption_default(pkg, key,
				    ucl_object_tostring(cur));
			break;
		case PKG_OPTION_DESCRIPTIONS:
			if (cur->type != UCL_STRING)
				pkg_emit_error("Skipping malformed option description %s",
				    key);
			else
				pkg_addoption_description(pkg, key,
				    ucl_object_tostring(cur));
			break;
		case PKG_SCRIPTS:
			if (cur->type != UCL_STRING)
				pkg_emit_error("Skipping malformed scripts %s",
				    key);
			else {
				script_type = script_type_str(key);
				if (script_type == PKG_SCRIPT_UNKNOWN) {
					pkg_emit_error("Skipping unknown script "
					    "type: %s", key);
					break;
				}

				urldecode(ucl_object_tostring(cur), &tmp);
				pkg_addscript(pkg, sbuf_data(tmp), script_type);
			}
			break;
		case PKG_ANNOTATIONS:
			if (cur->type != UCL_STRING)
				pkg_emit_error("Skipping malformed annotation %s",
				    key);
			else
				pkg_addannotation(pkg, key, ucl_object_tostring(cur));
			break;
		}
	}

	sbuf_free(tmp);

	return (EPKG_OK);
}
示例#4
0
static int
parse_mapping(struct pkg *pkg, yaml_node_t *item, yaml_document_t *doc, int attr)
{
	struct sbuf *tmp = NULL;
	yaml_node_pair_t *pair;
	yaml_node_t *key;
	yaml_node_t *val;
	pkg_script script_type;

	pair = item->data.mapping.pairs.start;

	while (pair < item->data.mapping.pairs.top) {
		key = yaml_document_get_node(doc, pair->key);
		val = yaml_document_get_node(doc, pair->value);

		if (key->data.scalar.length <= 0) {
			pkg_emit_error("Skipping empty dependency name");
			++pair;
			continue;
		}

		switch (attr) {
		case PKG_DEPS:
			if (val->type != YAML_MAPPING_NODE)
				pkg_emit_error("Skipping malformed dependency %s",
				    key->data.scalar.value);
			else
				pkg_set_deps_from_node(pkg, val, doc,
				    key->data.scalar.value);
			break;
		case PKG_DIRS:
			if (val->type != YAML_MAPPING_NODE)
				pkg_emit_error("Skipping malformed dirs %s",
				    key->data.scalar.value);
			else
				pkg_set_dirs_from_node(pkg, val, doc,
				    key->data.scalar.value);
			break;
		case PKG_USERS:
			if (is_valid_yaml_scalar(val))
				pkg_adduid(pkg, key->data.scalar.value,
				    val->data.scalar.value);
			else
				pkg_emit_error("Skipping malformed users %s",
						key->data.scalar.value);
			break;
		case PKG_GROUPS:
			if (is_valid_yaml_scalar(val))
				pkg_addgid(pkg, key->data.scalar.value,
				    val->data.scalar.value);
			else
				pkg_emit_error("Skipping malformed groups %s",
						key->data.scalar.value);
			break;
		case PKG_DIRECTORIES:
			if (is_valid_yaml_scalar(val)) {
				urldecode(key->data.scalar.value, &tmp);
				if (val->data.scalar.value[0] == 'y')
					pkg_adddir(pkg, sbuf_get(tmp), 1, false);
				else
					pkg_adddir(pkg, sbuf_get(tmp), 0, false);
			} else if (val->type == YAML_MAPPING_NODE) {
				pkg_set_dirs_from_node(pkg, val, doc,
				    key->data.scalar.value);
			} else {
				pkg_emit_error("Skipping malformed directories %s",
				    key->data.scalar.value);
			}
			break;
		case PKG_FILES:
			if (is_valid_yaml_scalar(val)) {
				const char *pkg_sum = NULL;
				if (val->data.scalar.length == 64)
					pkg_sum = val->data.scalar.value;
				urldecode(key->data.scalar.value, &tmp);
				pkg_addfile(pkg, sbuf_get(tmp), pkg_sum, false);
			} else if (val->type == YAML_MAPPING_NODE)
				pkg_set_files_from_node(pkg, val, doc,
				    key->data.scalar.value);
			else
				pkg_emit_error("Skipping malformed files %s",
				    key->data.scalar.value);
			break;
		case PKG_OPTIONS:
			if (val->type != YAML_SCALAR_NODE)
				pkg_emit_error("Skipping malformed option %s",
				    key->data.scalar.value);
			else
				pkg_addoption(pkg, key->data.scalar.value,
				    val->data.scalar.value);
			break;
		case PKG_SCRIPTS:
			if (val->type != YAML_SCALAR_NODE)
				pkg_emit_error("Skipping malformed scripts %s",
				    key->data.scalar.value);
			script_type = script_type_str(key->data.scalar.value);
			if (script_type == PKG_SCRIPT_UNKNOWN) {
				pkg_emit_error("Skipping unknown script "
				    "type: %s", key->data.scalar.value);
				break;
			}

			urldecode(val->data.scalar.value, &tmp);
			pkg_addscript(pkg, sbuf_get(tmp), script_type);
			break;
		}

		++pair;
	}

	sbuf_free(tmp);
	return (EPKG_OK);
}