Esempio n. 1
0
int
format_exec_cmd(char **dest, const char *in, const char *prefix, const char *plist_file)
{
	struct sbuf *buf = sbuf_new_auto();
	char path[MAXPATHLEN + 1];
	char *cp;

	while (in[0] != '\0') {
		if (in[0] == '%') {
			in++;
			switch(in[0]) {
				case 'D':
					sbuf_cat(buf, prefix);
					break;
				case 'F':
					sbuf_cat(buf, plist_file);
					break;
				case 'f':
					if (prefix[strlen(prefix) - 1] == '/')
						snprintf(path, sizeof(path), "%s%s", prefix, plist_file);
					else
						snprintf(path, sizeof(path), "%s/%s", prefix, plist_file);
					cp = strrchr(path, '/');
					cp ++;
					sbuf_cat(buf, cp);
					break;
				case 'B':
					if (prefix[strlen(prefix) - 1] == '/')
						snprintf(path, sizeof(path), "%s%s", prefix, plist_file);
					else
						snprintf(path, sizeof(path), "%s/%s", prefix, plist_file);
					cp = strrchr(path, '/');
					cp[0] = '\0';
					sbuf_cat(buf, path);
					break;
				default:
					sbuf_putc(buf, in[0]);
					break;
			}

		} else {
			sbuf_putc(buf, in[0]);
		}

		in++;
	}

	sbuf_finish(buf);
	*dest = strdup(sbuf_data(buf));
	sbuf_free(buf);
	
	return (0);
}
Esempio n. 2
0
static char *
sbuf_json_escape(struct sbuf *buf, const char *str)
{
	sbuf_clear(buf);
	while (str != NULL && *str != '\0') {
		if (*str == '"' || *str == '\\')
			sbuf_putc(buf, '\\');
		sbuf_putc(buf, *str);
		str++;
	}
	sbuf_finish(buf);

	return (sbuf_data(buf));
}
Esempio n. 3
0
static int
sbuf_copy_lines(struct sbuf *to, const char *from, int N)
{
	int cnt = 0;
	int i;

	if (N == 0)
		return (0);

	for (i = 0; from[i] != '\0'; i++) {
		if (from[i] == '\n') {
			cnt++;
			continue;
		}
		if (cnt == N)
			break;
	}

	if (to == NULL)
		return (i);
		
	if (sbuf_len(to) > 0 &&
	    sbuf_data(to)[sbuf_len(to)-1] != '\n')
		sbuf_putc(to, '\n');
	sbuf_bcat(to, from, i);
	sbuf_finish(to);

	return (i);
}
Esempio n. 4
0
File: annotate.c Progetto: dpl0/pkg
static struct sbuf *
read_input(void)
{
	struct sbuf	*input;
	int		 ch;

	input = sbuf_new_auto();

	for (;;) {
		ch = getc(stdin);
		if (ch == EOF) {
			if (feof(stdin))
				break;
			if (ferror(stdin))
				err(EX_NOINPUT, "Failed to read stdin");
		}
		sbuf_putc(input, ch);
	}
#ifdef __DragonFly__
	sbuf_finish(input);
#else
	if (sbuf_finish(input) != 0)
		err(EX_DATAERR, "Could not read value data");
#endif

	return (input);
}
Esempio n. 5
0
/* construct path to node->name */
static char *
mtree_file_path(fsnode *node)
{
	fsnode *pnode;
	struct sbuf *sb;
	char *res, *rp[MAKEFS_MAX_TREE_DEPTH];
	int depth;

	depth = 0;
	rp[depth] = node->name;
	for (pnode = node->parent; pnode && depth < MAKEFS_MAX_TREE_DEPTH;
	     pnode = pnode->parent) {
		if (strcmp(pnode->name, ".") == 0)
			break;
		rp[++depth] = pnode->name;
	}
	
	sb = sbuf_new_auto();
	if (sb == NULL) {
		errno = ENOMEM;
		return (NULL);
	}
	while (depth > 0) {
		sbuf_cat(sb, rp[depth--]);
		sbuf_putc(sb, '/');
	}
	sbuf_cat(sb, rp[depth]);
	sbuf_finish(sb);
	res = strdup(sbuf_data(sb));
	sbuf_delete(sb);
	if (res == NULL)
		errno = ENOMEM;
	return res;

}
Esempio n. 6
0
File: utils.c Progetto: baitisj/pkg
static int
ucl_sbuf_append_character(unsigned char c, size_t len, void *data)
{
	struct sbuf *buf = data;
	size_t i;

	for (i = 0; i < len; i++)
		sbuf_putc(buf, c);

	return (0);
}
Esempio n. 7
0
int
procfs_doproctype(PFS_FILL_ARGS)
{
	static const char *none = "Not Available";

	if (p != NULL && p->p_sysent && p->p_sysent->sv_name)
		sbuf_printf(sb, "%s", p->p_sysent->sv_name);
	else
		sbuf_printf(sb, "%s", none);
	sbuf_putc(sb, '\n');
	return (0);
}
Esempio n. 8
0
static int
urldecode(const char *src, struct sbuf **dest)
{
	size_t len;
	size_t i;
	char c;
	char hex[] = {'\0', '\0', '\0'};

	sbuf_init(dest);

	len = strlen(src);
	for (i = 0; i < len; i++) {
		if (src[i] != '%') {
			sbuf_putc(*dest, src[i]);
		} else {
			if (i + 2 > len) {
				pkg_emit_error("unexpected end of string");
				return (EPKG_FATAL);
			}

			hex[0] = src[++i];
			hex[1] = src[++i];
			errno = 0;
			c = strtol(hex, NULL, 16);
			if (errno != 0) {
				/*
				 * if it fails consider this is not a urlencoded
				 * information
				 */
				sbuf_printf(*dest, "%%%s", hex);
			} else {
				sbuf_putc(*dest, c);
			}
		}
	}
	sbuf_finish(*dest);

	return (EPKG_OK);
}
Esempio n. 9
0
static int
urldecode(const char *src, struct sbuf **dest)
{
	size_t len;
	size_t i;
	char c;
	char hex[] = {'\0', '\0', '\0'};

	if (*dest == NULL)
		*dest = sbuf_new_auto();
	else
		sbuf_reset(*dest);

	len = strlen(src);
	for (i = 0; i < len; i++) {
		if (src[i] != '%') {
			sbuf_putc(*dest, src[i]);
		} else {
			if (i + 2 > len) {
				pkg_emit_error("unexpected end of string");
				return (EPKG_FATAL);
			}

			hex[0] = src[++i];
			hex[1] = src[++i];
			errno = 0;
			c = strtol(hex, NULL, 16);
			if (errno != 0) {
				pkg_emit_errno("strtol()", hex);
				return (EPKG_FATAL);
			}
			sbuf_putc(*dest, c);
		}
	}
	sbuf_finish(*dest);

	return (EPKG_OK);
}
Esempio n. 10
0
/*------- API comments for these methods can be found in xenstorevar.h -------*/
struct sbuf *
xs_join(const char *dir, const char *name)
{
	struct sbuf *sb;

	sb = sbuf_new_auto();
	sbuf_cat(sb, dir);
	if (name[0] != '\0') {
		sbuf_putc(sb, '/');
		sbuf_cat(sb, name);
	}
	sbuf_finish(sb);

	return (sb);
}
Esempio n. 11
0
static int
urlencode(const char *src, struct sbuf **dest)
{
	size_t len;
	size_t i;

	sbuf_init(dest);

	len = strlen(src);
	for (i = 0; i < len; i++) {
		if (!isascii(src[i]) || src[i] == '%')
			sbuf_printf(*dest, "%%%.2x", (unsigned char)src[i]);
		else
			sbuf_putc(*dest, src[i]);
	}
	sbuf_finish(*dest);

	return (EPKG_OK);
}
Esempio n. 12
0
int
pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags)
{
	struct ucl_parser *p = NULL;
	size_t i;
	const char *val = NULL;
	const char *buf, *walk, *value, *key, *k;
	const char *evkey = NULL;
	const char *nsname = NULL;
	const char *evpipe = NULL;
	const ucl_object_t *cur, *object;
	ucl_object_t *obj = NULL, *o, *ncfg;
	ucl_object_iter_t it = NULL;
	struct sbuf *ukey = NULL;
	bool fatal_errors = false;

	k = NULL;
	o = NULL;

	pkg_get_myarch(myabi, BUFSIZ);
	pkg_get_myarch_legacy(myabi_legacy, BUFSIZ);
	if (parsed != false) {
		pkg_emit_error("pkg_init() must only be called once");
		return (EPKG_FATAL);
	}

	if (((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4) &&
	    ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)) {
		pkg_emit_error("Invalid flags for pkg_init()");
		return (EPKG_FATAL);
	}

	config = ucl_object_typed_new(UCL_OBJECT);

	for (i = 0; i < c_size; i++) {
		switch (c[i].type) {
		case PKG_STRING:
			obj = ucl_object_fromstring_common(
			    c[i].def != NULL ? c[i].def : "", 0, UCL_STRING_TRIM);
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_INT:
			ucl_object_insert_key(config,
			    ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT),
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_BOOL:
			ucl_object_insert_key(config,
			    ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN),
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_OBJECT:
			obj = ucl_object_typed_new(UCL_OBJECT);
			if (c[i].def != NULL) {
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
					key = walk;
					value = walk;
					while (*value != ',') {
						if (*value == '=')
							break;
						value++;
					}
					ucl_object_insert_key(obj,
					    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
					    key, value - key, false);
					buf++;
					walk = buf;
				}
				key = walk;
				value = walk;
				while (*value != ',') {
					if (*value == '=')
						break;
					value++;
				}
				if (o == NULL)
					o = ucl_object_typed_new(UCL_OBJECT);
				ucl_object_insert_key(o,
				    ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
				    key, value - key, false);
			}
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		case PKG_ARRAY:
			obj = ucl_object_typed_new(UCL_ARRAY);
			if (c[i].def != NULL) {
				walk = buf = c[i].def;
				while ((buf = strchr(buf, ',')) != NULL) {
					ucl_array_append(obj,
					    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
					buf++;
					walk = buf;
				}
				ucl_array_append(obj,
				    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
			}
			ucl_object_insert_key(config, obj,
			    c[i].key, strlen(c[i].key), false);
			break;
		}
	}

	if (path == NULL)
		path = PREFIX"/etc/pkg.conf";

	p = ucl_parser_new(0);

	errno = 0;
	obj = NULL;
	if (!ucl_parser_add_file(p, path)) {
		if (errno != ENOENT)
			pkg_emit_error("Invalid configuration file: %s", ucl_parser_get_error(p));
	} else {
		obj = ucl_parser_get_object(p);

	}

	ncfg = NULL;
	while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) {
		sbuf_init(&ukey);
		key = ucl_object_key(cur);
		for (i = 0; key[i] != '\0'; i++)
			sbuf_putc(ukey, toupper(key[i]));
		sbuf_finish(ukey);
		object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey));

		if (strncasecmp(sbuf_data(ukey), "PACKAGESITE", sbuf_len(ukey))
		    == 0 || strncasecmp(sbuf_data(ukey), "PUBKEY",
		    sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey),
		    "MIRROR_TYPE", sbuf_len(ukey)) == 0) {
			pkg_emit_error("%s in pkg.conf is no longer "
			    "supported.  Convert to the new repository style."
			    "  See pkg.conf(5)", sbuf_data(ukey));
			fatal_errors = true;
			continue;
		}

		/* ignore unknown keys */
		if (object == NULL)
			continue;

		if (object->type != cur->type) {
			pkg_emit_error("Malformed key %s, ignoring", key);
			continue;
		}

		if (ncfg == NULL)
			ncfg = ucl_object_typed_new(UCL_OBJECT);
		ucl_object_insert_key(ncfg, ucl_object_copy(cur), sbuf_data(ukey), sbuf_len(ukey), true);
	}

	if (fatal_errors) {
		ucl_object_unref(ncfg);
		ucl_parser_free(p);
		return (EPKG_FATAL);
	}

	if (ncfg != NULL) {
		it = NULL;
		while (( cur = ucl_iterate_object(ncfg, &it, true))) {
			key = ucl_object_key(cur);
			ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true);
		}
		ucl_object_unref(ncfg);
	}

	ncfg = NULL;
	it = NULL;
	while ((cur = ucl_iterate_object(config, &it, true))) {
		o = NULL;
		key = ucl_object_key(cur);
		val = getenv(key);
		if (val == NULL)
			continue;
		switch (cur->type) {
		case UCL_STRING:
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM);
			break;
		case UCL_INT:
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT);
			if (o->type != UCL_INT) {
				pkg_emit_error("Invalid type for environment "
				    "variable %s, got %s, while expecting an integer",
				    key, val);
				ucl_object_unref(o);
				continue;
			}
			break;
		case UCL_BOOLEAN:
			o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN);
			if (o->type != UCL_BOOLEAN) {
				pkg_emit_error("Invalid type for environment "
				    "variable %s, got %s, while expecting a boolean",
				    key, val);
				ucl_object_unref(o);
				continue;
			}
			break;
		case UCL_OBJECT:
			o = ucl_object_typed_new(UCL_OBJECT);
			walk = buf = val;
			while ((buf = strchr(buf, ',')) != NULL) {
				k = walk;
				value = walk;
				while (*value != ',') {
					if (*value == '=')
						break;
					value++;
				}
				ucl_object_insert_key(o,
				    ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM),
				    k, value - k, false);
				buf++;
				walk = buf;
			}
			key = walk;
			value = walk;
			while (*value != '\0') {
				if (*value == '=')
					break;
				value++;
			}
			ucl_object_insert_key(o,
			    ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM),
			    k, value - k, false);
			break;
		case UCL_ARRAY:
			o = ucl_object_typed_new(UCL_ARRAY);
			walk = buf = val;
			while ((buf = strchr(buf, ',')) != NULL) {
				ucl_array_append(o,
				    ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM));
				buf++;
				walk = buf;
			}
			ucl_array_append(o,
			    ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM));
			break;
		default:
			/* ignore other types */
			break;
		}
		if (o != NULL) {
			if (ncfg == NULL)
				ncfg = ucl_object_typed_new(UCL_OBJECT);
			ucl_object_insert_key(ncfg, o, key, strlen(key), true);
		}
	}

	if (ncfg != NULL) {
		it = NULL;
		while (( cur = ucl_iterate_object(ncfg, &it, true))) {
			key = ucl_object_key(cur);
			ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true);
		}
		ucl_object_unref(ncfg);
	}

	disable_plugins_if_static();

	parsed = true;
	ucl_object_unref(obj);
	ucl_parser_free(p);

	if (strcmp(pkg_object_string(pkg_config_get("ABI")), "unknown") == 0) {
		pkg_emit_error("Unable to determine ABI");
		return (EPKG_FATAL);
	}

	pkg_debug(1, "%s", "pkg initialized");

	/* Start the event pipe */
	evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE"));
	if (evpipe != NULL)
		connect_evpipe(evpipe);

	debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL"));

	it = NULL;
	object = ucl_object_find_key(config, "PKG_ENV");
	while ((cur = ucl_iterate_object(object, &it, true))) {
		evkey = ucl_object_key(cur);
		pkg_debug(1, "Setting env var: %s", evkey);
		if (evkey != NULL && evkey[0] != '\0')
			setenv(evkey, ucl_object_tostring_forced(cur), 1);
	}

	/* load the repositories */
	load_repositories(reposdir, flags);

	setenv("HTTP_USER_AGENT", "pkg/"PKGVERSION, 1);

	/* bypass resolv.conf with specified NAMESERVER if any */
	nsname = pkg_object_string(pkg_config_get("NAMESERVER"));
	if (nsname != NULL)
		set_nameserver(ucl_object_tostring_forced(o));

	return (EPKG_OK);
}
Esempio n. 13
0
File: utils.c Progetto: baloo/pkgng
int
format_exec_cmd(char **dest, const char *in, const char *prefix, const char *plist_file, char *line)
{
	struct sbuf *buf = sbuf_new_auto();
	char path[MAXPATHLEN + 1];
	char *cp;

	while (in[0] != '\0') {
		if (in[0] == '%') {
			in++;
			switch(in[0]) {
				case 'D':
					sbuf_cat(buf, prefix);
					break;
				case 'F':
					if (plist_file == NULL) {
						pkg_emit_error("No files defined %%F couldn't be expanded, ignoring %s", in);
						sbuf_finish(buf);
						sbuf_free(buf);
						return (EPKG_FATAL);
					}
					sbuf_cat(buf, plist_file);
					break;
				case 'f':
					if (plist_file == NULL) {
						pkg_emit_error("No files defined %%f couldn't be expanded, ignoring %s", in);
						sbuf_finish(buf);
						sbuf_free(buf);
						return (EPKG_FATAL);
					}
					if (prefix[strlen(prefix) - 1] == '/')
						snprintf(path, sizeof(path), "%s%s", prefix, plist_file);
					else
						snprintf(path, sizeof(path), "%s/%s", prefix, plist_file);
					cp = strrchr(path, '/');
					cp ++;
					sbuf_cat(buf, cp);
					break;
				case 'B':
					if (plist_file == NULL) {
						pkg_emit_error("No files defined %%B couldn't be expanded, ignoring %s", in);
						sbuf_finish(buf);
						sbuf_free(buf);
						return (EPKG_FATAL);
					}
					if (prefix[strlen(prefix) - 1] == '/')
						snprintf(path, sizeof(path), "%s%s", prefix, plist_file);
					else
						snprintf(path, sizeof(path), "%s/%s", prefix, plist_file);
					cp = strrchr(path, '/');
					cp[0] = '\0';
					sbuf_cat(buf, path);
					break;
				case '%':
					sbuf_putc(buf, '%');
					break;
				case '@':
					if (line != NULL) {
						sbuf_cat(buf, line);
						break;
					}

					/*
					 * no break here because if line is not
					 * given (default exec) %@ does not
					 * exists
					 */
				default:
					sbuf_putc(buf, '%');
					sbuf_putc(buf, in[0]);
					break;
			}

		} else {
			sbuf_putc(buf, in[0]);
		}

		in++;
	}

	sbuf_finish(buf);
	*dest = strdup(sbuf_data(buf));
	sbuf_free(buf);
	
	return (EPKG_OK);
}
Esempio n. 14
0
File: query.c Progetto: culot/pkgng
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
	char size[7];
	const char *tmp;
	bool automatic;
	int64_t flatsize;
	lic_t licenselogic;

	sbuf_clear(dest);

	while (qstr[0] != '\0') {
		if (qstr[0] == '%') {
			qstr++;
			switch (qstr[0]) {
				case 'n':
					pkg_get(pkg, PKG_NAME, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'v':
					pkg_get(pkg, PKG_VERSION, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'o':
					pkg_get(pkg, PKG_ORIGIN, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'p':
					pkg_get(pkg, PKG_PREFIX, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'm':
					pkg_get(pkg, PKG_MAINTAINER, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'c':
					pkg_get(pkg, PKG_COMMENT, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'w':
					pkg_get(pkg, PKG_WWW, &tmp);
					sbuf_cat(dest, tmp);
					break;
				case 'a':
					pkg_get(pkg, PKG_AUTOMATIC, &automatic);
					sbuf_printf(dest, "%d", automatic);
					break;
				case 's':
					qstr++;
					pkg_get(pkg, PKG_FLATSIZE, &flatsize);
					if (qstr[0] == 'h') {
						humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0);
						sbuf_cat(dest, size);
					} else if (qstr[0] == 'b') {
						sbuf_printf(dest, "%" PRId64, flatsize);
					}
					break;
				case '?':
					qstr++;
					switch (qstr[0]) {
						case 'd':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DEPS));
							break;
						case 'r':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_RDEPS));
							break;
						case 'C':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_CATEGORIES));
							break;
						case 'F':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_FILES));
							break;
						case 'O':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_OPTIONS));
							break;
						case 'D':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DIRS));
							break;
						case 'L':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_LICENSES));
							break;
						case 'U':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_USERS));
							break;
						case 'G':
							sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_GROUPS));
							break;
					}
					break;
				case 'l':
					pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic);
					switch (licenselogic) {
						case LICENSE_SINGLE:
							sbuf_cat(dest, "single");
							break;
						case LICENSE_OR:
							sbuf_cat(dest, "or");
							break;
						case LICENSE_AND:
							sbuf_cat(dest, "and");
							break;
					}
					break;
				case 'd':
					qstr++;
					if (qstr[0] == 'n')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_NAME));
					else if (qstr[0] == 'o')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN));
					else if (qstr[0] == 'v')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION));
					break;
				case 'r':
					qstr++;
					if (qstr[0] == 'n')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_NAME));
					else if (qstr[0] == 'o')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN));
					else if (qstr[0] == 'v')
						sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION));
					break;
				case 'C':
					sbuf_cat(dest, pkg_category_name((struct pkg_category *)data));
					break;
				case 'F':
					qstr++;
					if (qstr[0] == 'p')
						sbuf_cat(dest, pkg_file_get((struct pkg_file *)data, PKG_FILE_PATH));
					else if (qstr[0] == 's')
						sbuf_cat(dest, pkg_file_get((struct pkg_file *)data, PKG_FILE_SUM));
					break;
				case 'S':
					sbuf_cat(dest, pkg_script_data((struct pkg_script *)data));	
					break;
				case 'O':
					qstr++;
					if (qstr[0] == 'k')
						sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data));
					else if (qstr[0] == 'v')
						sbuf_cat(dest, pkg_option_value((struct pkg_option *)data));
					break;
				case 'D':
					sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data));
					break;
				case 'L':
					sbuf_cat(dest, pkg_license_name((struct pkg_license *)data));
					break;
				case 'U':
					sbuf_cat(dest, pkg_user_name((struct pkg_user *)data));
					break;
				case 'G':
					sbuf_cat(dest, pkg_group_name((struct pkg_group *)data));
					break;
				case '%':
					sbuf_putc(dest, '%');
					break;
			}
		} else  if (qstr[0] == '\\') {
			qstr++;
			switch (qstr[0]) {
				case 'n':
					sbuf_putc(dest, '\n');
					break;
				case 'a':
					sbuf_putc(dest, '\a');
					break;
				case 'b':
					sbuf_putc(dest, '\b');
					break;
				case 'f':
					sbuf_putc(dest, '\f');
					break;
				case 'r':
					sbuf_putc(dest, '\r');
					break;
				case '\\':
					sbuf_putc(dest, '\\');
					break;
				case 't':
					sbuf_putc(dest, '\t');
					break;
			}
		} else {
			sbuf_putc(dest, qstr[0]);
		}
		qstr++;
	}
	sbuf_finish(dest);
}
Esempio n. 15
0
int
procfs_doprocstatus(PFS_FILL_ARGS)
{
	struct session *sess;
	struct thread *tdfirst;
	struct tty *tp;
	struct ucred *cr;
	const char *wmesg;
	char *pc;
	char *sep;
	int pid, ppid, pgid, sid;
	int i;

	pid = p->p_pid;
	PROC_LOCK(p);
	ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
	pgid = p->p_pgrp->pg_id;
	sess = p->p_pgrp->pg_session;
	SESS_LOCK(sess);
	sid = sess->s_leader ? sess->s_leader->p_pid : 0;

/* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg
				euid ruid rgid,egid,groups[1 .. ngroups]
*/

	pc = p->p_comm;
	do {
		if (*pc < 33 || *pc > 126 || *pc == '\\')
			sbuf_printf(sb, "\\%03o", *pc);
		else
			sbuf_putc(sb, *pc);
	} while (*++pc);
	sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid);
	if ((p->p_flag & P_CONTROLT) && (tp = sess->s_ttyp))
		sbuf_printf(sb, "%s ", devtoname(tp->t_dev));
	else
		sbuf_printf(sb, "- ");

	sep = "";
	if (sess->s_ttyvp) {
		sbuf_printf(sb, "%sctty", sep);
		sep = ",";
	}
	if (SESS_LEADER(p)) {
		sbuf_printf(sb, "%ssldr", sep);
		sep = ",";
	}
	SESS_UNLOCK(sess);
	if (*sep != ',') {
		sbuf_printf(sb, "noflags");
	}

	tdfirst = FIRST_THREAD_IN_PROC(p);
	thread_lock(tdfirst);
	if (tdfirst->td_wchan != NULL) {
		KASSERT(tdfirst->td_wmesg != NULL,
		    ("wchan %p has no wmesg", tdfirst->td_wchan));
		wmesg = tdfirst->td_wmesg;
	} else
		wmesg = "nochan";
	thread_unlock(tdfirst);

	if (p->p_flag & P_INMEM) {
		struct timeval start, ut, st;

		PROC_SLOCK(p);
		calcru(p, &ut, &st);
		PROC_SUNLOCK(p);
		start = p->p_stats->p_start;
		timevaladd(&start, &boottime);
		sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld",
		    (intmax_t)start.tv_sec, start.tv_usec,
		    (intmax_t)ut.tv_sec, ut.tv_usec,
		    (intmax_t)st.tv_sec, st.tv_usec);
	} else
		sbuf_printf(sb, " -1,-1 -1,-1 -1,-1");

	sbuf_printf(sb, " %s", wmesg);

	cr = p->p_ucred;

	sbuf_printf(sb, " %lu %lu %lu",
		(u_long)cr->cr_uid,
		(u_long)cr->cr_ruid,
		(u_long)cr->cr_rgid);

	/* egid (cr->cr_svgid) is equal to cr_ngroups[0]
	   see also getegid(2) in /sys/kern/kern_prot.c */

	for (i = 0; i < cr->cr_ngroups; i++) {
		sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]);
	}

	if (jailed(cr)) {
		mtx_lock(&cr->cr_prison->pr_mtx);
		sbuf_printf(sb, " %s",
		    prison_name(td->td_ucred->cr_prison, cr->cr_prison));
		mtx_unlock(&cr->cr_prison->pr_mtx);
	} else {
		sbuf_printf(sb, " -");
	}
	PROC_UNLOCK(p);
	sbuf_printf(sb, "\n");

	return (0);
}
Esempio n. 16
0
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const void *data)
{
	bool automatic;
	bool locked;

	sbuf_clear(dest);

	while (qstr[0] != '\0') {
		if (qstr[0] == '%') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				pkg_sbuf_printf(dest, "%n", pkg);
				break;
			case 'v':
				pkg_sbuf_printf(dest, "%v", pkg);
				break;
			case 'o':
				pkg_sbuf_printf(dest, "%o", pkg);
				break;
			case 'R':
				pkg_sbuf_printf(dest, "%N", pkg);
				break;
			case 'p':
				pkg_sbuf_printf(dest, "%p", pkg);
				break;
			case 'm':
				pkg_sbuf_printf(dest, "%m", pkg);
				break;
			case 'c':
				pkg_sbuf_printf(dest, "%c", pkg);
				break;
			case 'w':
				pkg_sbuf_printf(dest, "%w", pkg);
				break;
			case 'a':
				pkg_get(pkg, PKG_AUTOMATIC, &automatic);
				sbuf_printf(dest, "%d", automatic);
				break;
			case 'k':
				pkg_get(pkg, PKG_LOCKED, &locked);
				sbuf_printf(dest, "%d", locked);
				break;
			case 't':
				pkg_sbuf_printf(dest, "%t", pkg);
				break;
			case 's':
				qstr++;
				if (qstr[0] == 'h') 
					pkg_sbuf_printf(dest, "%#sB", pkg);
			        else if (qstr[0] == 'b')
					pkg_sbuf_printf(dest, "%s", pkg);
				break;
			case 'e':
				pkg_sbuf_printf(dest, "%e", pkg);
				break;
			case '?':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					pkg_sbuf_printf(dest, "%?d", pkg);
					break;
				case 'r':
					pkg_sbuf_printf(dest, "%?r", pkg);
					break;
				case 'C':
					pkg_sbuf_printf(dest, "%?C", pkg);
					break;
				case 'F':
					pkg_sbuf_printf(dest, "%?F", pkg);
					break;
				case 'O':
					pkg_sbuf_printf(dest, "%?O", pkg);
					break;
				case 'D':
					pkg_sbuf_printf(dest, "%?D", pkg);
					break;
				case 'L':
					pkg_sbuf_printf(dest, "%?L", pkg);
					break;
				case 'U':
					pkg_sbuf_printf(dest, "%?U", pkg);
					break;
				case 'G':
					pkg_sbuf_printf(dest, "%?G", pkg);
					break;
				case 'B':
					pkg_sbuf_printf(dest, "%?B", pkg);
					break;
				case 'b':
					pkg_sbuf_printf(dest, "%?b", pkg);
					break;
				case 'A':
					pkg_sbuf_printf(dest, "%?A", pkg);
					break;
				}
				break;
			case '#':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					pkg_sbuf_printf(dest, "%#d", pkg);
					break;
				case 'r':
					pkg_sbuf_printf(dest, "%#r", pkg);
					break;
				case 'C':
					pkg_sbuf_printf(dest, "%#C", pkg);
					break;
				case 'F':
					pkg_sbuf_printf(dest, "%#F", pkg);
					break;
				case 'O':
					pkg_sbuf_printf(dest, "%#O", pkg);
					break;
				case 'D':
					pkg_sbuf_printf(dest, "%#D", pkg);
					break;
				case 'L':
					pkg_sbuf_printf(dest, "%#L", pkg);
					break;
				case 'U':
					pkg_sbuf_printf(dest, "%#U", pkg);
					break;
				case 'G':
					pkg_sbuf_printf(dest, "%#G", pkg);
					break;
				case 'B':
					pkg_sbuf_printf(dest, "%#B", pkg);
					break;
				case 'b':
					pkg_sbuf_printf(dest, "%#b", pkg);
					break;
				case 'A':
					pkg_sbuf_printf(dest, "%#A", pkg);
					break;
				}
				break;
			case 'q':
				pkg_sbuf_printf(dest, "%q", pkg);
				break;
			case 'l':
				pkg_sbuf_printf(dest, "%l", pkg);
				break;
			case 'd':
				qstr++;
				if (qstr[0] == 'n')
					pkg_sbuf_printf(dest, "%dn", data);
				else if (qstr[0] == 'o')
					pkg_sbuf_printf(dest, "%do", data);
				else if (qstr[0] == 'v')
					pkg_sbuf_printf(dest, "%dv", data);
				break;
			case 'r':
				qstr++;
				if (qstr[0] == 'n')
					pkg_sbuf_printf(dest, "%rn", data);
				else if (qstr[0] == 'o')
					pkg_sbuf_printf(dest, "%ro", data);
				else if (qstr[0] == 'v')
					pkg_sbuf_printf(dest, "%rv", data);
				break;
			case 'C':
				pkg_sbuf_printf(dest, "%Cn", data);
				break;
			case 'F':
				qstr++;
				if (qstr[0] == 'p')
					pkg_sbuf_printf(dest, "%Fn", data);
				else if (qstr[0] == 's')
					pkg_sbuf_printf(dest, "%Fs", data);
				break;
			case 'O':
				qstr++;
				if (qstr[0] == 'k')
					pkg_sbuf_printf(dest, "%On", data);
				else if (qstr[0] == 'v')
					pkg_sbuf_printf(dest, "%Ov", data);
				else if (qstr[0] == 'd') /* default value */
					pkg_sbuf_printf(dest, "%Od", data);
				else if (qstr[0] == 'D') /* description */
					pkg_sbuf_printf(dest, "%OD", data);
				break;
			case 'D':
				pkg_sbuf_printf(dest, "%Dn", data);
				break;
			case 'L':
				pkg_sbuf_printf(dest, "%Ln", data);
				break;
			case 'U':
				pkg_sbuf_printf(dest, "%Un", data);
				break;
			case 'G':
				pkg_sbuf_printf(dest, "%Gn", data);
				break;
			case 'B':
				pkg_sbuf_printf(dest, "%Bn", data);
				break;
			case 'b':
				pkg_sbuf_printf(dest, "%bn", data);
				break;
			case 'A':
				qstr++;
				if (qstr[0] == 't')
					pkg_sbuf_printf(dest, "%An", data);
				else if (qstr[0] == 'v')
					pkg_sbuf_printf(dest, "%Av", data);
				break;
			case 'M':
				if (pkg_has_message(pkg))
					pkg_sbuf_printf(dest, "%M", pkg);
				break;
			case '%':
				sbuf_putc(dest, '%');
				break;
			}
		} else  if (qstr[0] == '\\') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				sbuf_putc(dest, '\n');
				break;
			case 'a':
				sbuf_putc(dest, '\a');
				break;
			case 'b':
				sbuf_putc(dest, '\b');
				break;
			case 'f':
				sbuf_putc(dest, '\f');
				break;
			case 'r':
				sbuf_putc(dest, '\r');
				break;
			case '\\':
				sbuf_putc(dest, '\\');
				break;
			case 't':
				sbuf_putc(dest, '\t');
				break;
			}
		} else {
			sbuf_putc(dest, qstr[0]);
		}
		qstr++;
	}
	sbuf_finish(dest);
}
Esempio n. 17
0
int
format_sql_condition(const char *str, struct sbuf *sqlcond, bool for_remote)
{
	state_t state = NONE;
	unsigned int bracket_level = 0;
	const char *sqlop;

	sbuf_cat(sqlcond, " WHERE ");
	while (str[0] != '\0') {
		if (state == NONE) {
			if (str[0] == '%') {
				str++;
				switch (str[0]) {
				case 'n':
					sbuf_cat(sqlcond, "name");
					state = OPERATOR_STRING;
					break;
				case 'o':
					sbuf_cat(sqlcond, "origin");
					state = OPERATOR_STRING;
					break;
				case 'p':
					sbuf_cat(sqlcond, "prefix");
					state = OPERATOR_STRING;
					break;
				case 'm':
					sbuf_cat(sqlcond, "maintainer");
					state = OPERATOR_STRING;
					break;
				case 'c':
					sbuf_cat(sqlcond, "comment");
					state = OPERATOR_STRING;
					break;
				case 'w':
					sbuf_cat(sqlcond, "www");
					state = OPERATOR_STRING;
					break;
				case 's':
					sbuf_cat(sqlcond, "flatsize");
					state = OPERATOR_INT;
					break;
				case 'a':
					if (for_remote)
						goto bad_option;
					sbuf_cat(sqlcond, "automatic");
					state = OPERATOR_INT;
					break;
				case 'q':
					sbuf_cat(sqlcond, "arch");
					state = OPERATOR_STRING;
					break;
				case 'k':
					if (for_remote)
						goto bad_option;
					sbuf_cat(sqlcond, "locked");
					state = OPERATOR_INT;
					break;
				case 'M':
					if (for_remote)
						goto bad_option;
					sbuf_cat(sqlcond, "message");
					state = OPERATOR_STRING;
					break;
				case 't':
					if (for_remote)
						goto bad_option;
					sbuf_cat(sqlcond, "time");
					state = OPERATOR_INT;
					break;
				case 'e':
					sbuf_cat(sqlcond, "desc");
					state = OPERATOR_STRING;
					break;
				case '#': /* FALLTHROUGH */
				case '?':
					sqlop = (str[0] == '#' ? "COUNT(*)" : "COUNT(*) > 0");
					str++;
					switch (str[0]) {
						case 'd':
							sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'r':
							sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop);
							break;
						case 'C':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'F':
							if (for_remote)
								goto bad_option;
							sbuf_printf(sqlcond, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'O':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'D':
							if (for_remote)
								goto bad_option;
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'L':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'U':
							if (for_remote)
								goto bad_option;
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'G':
							if (for_remote)
								goto bad_option;
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'B':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'b':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop);
							break;
						case 'A':
							sbuf_printf(sqlcond, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop);
							break;
						default:
							goto bad_option;
					}
					state = OPERATOR_INT;
					break;
				default:
bad_option:
					fprintf(stderr, "malformed evaluation string\n");
					return (EPKG_FATAL);
				}
			} else {
				switch (str[0]) {
				case '(':
					bracket_level++;
					sbuf_putc(sqlcond, str[0]);
					break;
				case ' ':
				case '\t':
					break;
				default:
					fprintf(stderr, "unexpected character: %c\n", str[0]);
					return (EPKG_FATAL);
				}
			}
		} else if (state == POST_EXPR) {
			switch (str[0]) {
			case ')':
				if (bracket_level == 0) {
					fprintf(stderr, "too many closing brackets.\n");
					return (EPKG_FATAL);
				}
				bracket_level--;
				sbuf_putc(sqlcond, str[0]);
				break;
			case ' ':
			case '\t':
				break;
			case '|':
				if (str[1] == '|') {
					str++;
					state = NONE;
					sbuf_cat(sqlcond, " OR ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
					return (EPKG_FATAL);
				}
			case '&':
				if (str[1] == '&') {
					str++;
					state = NONE;
					sbuf_cat(sqlcond, " AND ");
					break;
				} else {
					fprintf(stderr, "unexpected character %c\n", str[1]);
					return (EPKG_FATAL);
				}
			default:
				fprintf(stderr, "unexpected character %c\n", str[0]);
				return (EPKG_FATAL);
			}
		} else if (state == OPERATOR_STRING || state == OPERATOR_INT) {
			/* only operators or space are allowed here */
			if (isspace(str[0])) {
				/* do nothing */
			} else if (str[0] == '~' ) {
				if (state != OPERATOR_STRING) {
					fprintf(stderr, "~ expected only for string testing\n");
					return (EPKG_FATAL);
				}
				state = NEXT_IS_STRING;
				sbuf_cat(sqlcond, " GLOB ");
			} else if (str[0] == '>' || str[0] == '<') {
				if (state != OPERATOR_INT) {
					fprintf(stderr, "> expected only for integers\n");
					return (EPKG_FATAL);
				}
				state = NEXT_IS_INT;
				sbuf_putc(sqlcond, str[0]);
				if (str[1] == '=') {
					str++;
					sbuf_putc(sqlcond, str[0]);
				}
			} else if (str[0] == '=') {
				if (state == OPERATOR_STRING) {
					state = NEXT_IS_STRING;
				} else {
					state = NEXT_IS_INT;
				}
				sbuf_putc(sqlcond, str[0]);
				if (str[1] == '=') {
					str++;
					sbuf_putc(sqlcond, str[0]);
				}
			} else if (str[0] == '!') {
				if (str[1] != '=') {
					fprintf(stderr, "expecting = after !\n");
					return (EPKG_FATAL);
				}
				if (state == OPERATOR_STRING) {
					state = NEXT_IS_STRING;
				} else {
					state = NEXT_IS_INT;
				}
				sbuf_putc(sqlcond, str[0]);
				str++;
				sbuf_putc(sqlcond, str[0]);
			} else {
				fprintf(stderr, "an operator is expected, got %c\n", str[0]);
				return (EPKG_FATAL);
			}
		} else if (state == NEXT_IS_STRING || state == NEXT_IS_INT) {
			if (isspace(str[0])) {
				/* do nothing */
			} else {
				if (state == NEXT_IS_STRING) {
					if (str[0] == '"') {
						state = QUOTEDSTRING;
					} else if (str[0] == '\'') {
						state = SQUOTEDSTRING;
					} else {
						state = STRING;
						str--;
					}
					sbuf_putc(sqlcond, '\'');
				} else {
					if (!isdigit(str[0])) {
						fprintf(stderr, "a number is expected, got: %c\n", str[0]);
						return (EPKG_FATAL);
					}
					state = INT;
					sbuf_putc(sqlcond, str[0]);
				}
			}
		} else if (state == INT) {
			if (!isdigit(str[0])) {
				state = POST_EXPR;
				str--;
			} else {
				sbuf_putc(sqlcond, str[0]);
			}
		} else if (state == STRING || state == QUOTEDSTRING || state == SQUOTEDSTRING) {
			if ((state == STRING && isspace(str[0])) ||
			    (state == QUOTEDSTRING && str[0] == '"') ||
			    (state == SQUOTEDSTRING && str[0] == '\'')) {
				sbuf_putc(sqlcond, '\'');
				state = POST_EXPR;
			} else {
				sbuf_putc(sqlcond, str[0]);
				if (str[0] == '\'')
					sbuf_putc(sqlcond, str[0]);
				else if (str[0] == '%' && for_remote)
					sbuf_putc(sqlcond, str[0]);
			}
		}
		str++;
	}
	if (state == STRING) {
		sbuf_putc(sqlcond, '\'');
		state = POST_EXPR;
	}

	if (state != POST_EXPR && state != INT) {
		fprintf(stderr, "unexpected end of expression\n");
		return (EPKG_FATAL);
	} else if (bracket_level > 0) {
		fprintf(stderr, "unexpected end of expression (too many open brackets)\n");
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
Esempio n. 18
0
File: utils.c Progetto: baitisj/pkg
int
format_exec_cmd(char **dest, const char *in, const char *prefix,
    const char *plist_file, char *line, int argc, char **argv)
{
	struct sbuf *buf = sbuf_new_auto();
	char path[MAXPATHLEN];
	char *cp;
	size_t sz;

	while (in[0] != '\0') {
		if (in[0] != '%') {
			sbuf_putc(buf, in[0]);
			in++;
			continue;
		}
		in++;
		switch(in[0]) {
		case 'D':
			sbuf_cat(buf, prefix);
			break;
		case 'F':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%F couldn't "
				    "be expanded, ignoring %s", in);
				sbuf_finish(buf);
				sbuf_free(buf);
				return (EPKG_FATAL);
			}
			sbuf_cat(buf, plist_file);
			break;
		case 'f':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%f couldn't "
				    "be expanded, ignoring %s", in);
				sbuf_finish(buf);
				sbuf_free(buf);
				return (EPKG_FATAL);
			}
			if (prefix[strlen(prefix) - 1] == '/')
				snprintf(path, sizeof(path), "%s%s",
				    prefix, plist_file);
			else
				snprintf(path, sizeof(path), "%s/%s",
				    prefix, plist_file);
			cp = strrchr(path, '/');
			cp ++;
			sbuf_cat(buf, cp);
			break;
		case 'B':
			if (plist_file == NULL || plist_file[0] == '\0') {
				pkg_emit_error("No files defined %%B couldn't "
				    "be expanded, ignoring %s", in);
				sbuf_finish(buf);
				sbuf_free(buf);
				return (EPKG_FATAL);
			}
			if (prefix[strlen(prefix) - 1] == '/')
				snprintf(path, sizeof(path), "%s%s", prefix,
				    plist_file);
			else
				snprintf(path, sizeof(path), "%s/%s", prefix,
				    plist_file);
			cp = strrchr(path, '/');
			cp[0] = '\0';
			sbuf_cat(buf, path);
			break;
		case '%':
			sbuf_putc(buf, '%');
			break;
		case '@':
			if (line != NULL) {
				sbuf_cat(buf, line);
				break;
			}

			/*
			 * no break here because if line is not
			 * given (default exec) %@ does not
			 * exists
			 */
		case '#':
			sbuf_putc(buf, argc);
			break;
		default:
			if ((sz = strspn(in, "0123456789")) > 0) {
				int pos = strtol(in, NULL, 10);
				if (pos > argc) {
					pkg_emit_error("Requesting argument "
					    "%%%d while only %d arguments are"
					    " available", pos, argc);
					sbuf_finish(buf);
					sbuf_free(buf);
					return (EPKG_FATAL);
				}
				sbuf_cat(buf, argv[pos -1]);
				in += sz -1;
				break;
			}
			sbuf_putc(buf, '%');
			sbuf_putc(buf, in[0]);
			break;
		}

		in++;
	}

	sbuf_finish(buf);
	*dest = strdup(sbuf_data(buf));
	sbuf_free(buf);
	
	return (EPKG_OK);
}
Esempio n. 19
0
struct t_rename_pattern *
t_rename_parse(const char *source)
{
	const char sep = '%';
	const char *c = source;
	struct t_rename_pattern *pattern = NULL;
	struct t_rename_token *token;
	struct sbuf *sb = NULL;
	enum {
		PARSING_STRING,
		PARSING_SIMPLE_TAG,
		PARSING_BRACE_TAG
	} state;

	sb = sbuf_new_auto();
	if (sb == NULL)
		goto error_label;

	pattern = malloc(sizeof(struct t_rename_pattern));
	if (pattern == NULL)
		goto error_label;
	TAILQ_INIT(pattern);

	state = PARSING_STRING;
	while (*c != '\0') {
		/* if we parse a litteral string, check if this is the start of
		   a tag */
		if (state == PARSING_STRING && *c == sep) {
			/* avoid to add a empty token. This can happen when
			   when parsing two consecutive tags like `%tag%tag' */
			if (sbuf_len(sb) > 0) {
				if (sbuf_finish(sb) == -1)
					goto error_label;
				token = t_rename_token_new(T_STRING, sbuf_data(sb));
				if (token == NULL)
					goto error_label;
				TAILQ_INSERT_TAIL(pattern, token, entries);
			}
			sbuf_clear(sb);
			c += 1;
			if (*c == '{') {
				c += 1;
				state = PARSING_BRACE_TAG;
			} else {
				state = PARSING_SIMPLE_TAG;
			}
		/* if we parse a tag, check for the end of it */
		} else if ((state == PARSING_SIMPLE_TAG && (*c == sep || !isalnum(*c))) ||
		           (state == PARSING_BRACE_TAG  && *c == '}')) {
			if (sbuf_len(sb) == 0)
				warnx("empty tag in rename pattern");
			if (sbuf_finish(sb) == -1)
				goto error_label;
			token = t_rename_token_new(T_TAG, sbuf_data(sb));
			if (token == NULL)
				goto error_label;
			sbuf_clear(sb);
			TAILQ_INSERT_TAIL(pattern, token, entries);
			if (state == PARSING_BRACE_TAG) {
				/* eat the closing `}' */
				c += 1;
			}
			state = PARSING_STRING;
		} else {
			/* default case for both string and tags. `\' escape
			   everything */
			if (*c == '\\') {
				c += 1;
				if (*c == '\0')
					break;
			}
			sbuf_putc(sb, *c);
			c += 1;
		}
	}
	/* we've hit the end of the source. Check in which state we are and try
	   to finish cleany */
	switch (state) {
	case PARSING_BRACE_TAG:
		warnx("missing closing `}' at the end of the rename pattern");
		goto error_label;
	case PARSING_SIMPLE_TAG:
		if (sbuf_len(sb) == 0)
			warnx("empty tag at the end of the rename pattern");
	case PARSING_STRING: /* FALLTHROUGH */
	default:
		/* all is right */;
	}
	/* finish the last tag unless it is the empty string */
	if (state != PARSING_STRING || sbuf_len(sb) > 0) {
		if (sbuf_finish(sb) == -1)
			goto error_label;
		token = t_rename_token_new(
			    (state == PARSING_STRING ? T_STRING : T_TAG),
			    sbuf_data(sb));
		if (token == NULL)
			goto error_label;
		TAILQ_INSERT_TAIL(pattern, token, entries);
	}

	sbuf_delete(sb);
	return (pattern);
	/* NOTREACHED */
error_label:
	sbuf_delete(sb);
	t_rename_pattern_delete(pattern);
	return (NULL);
}
Esempio n. 20
0
static void
config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype)
{
	struct sbuf *buf = sbuf_new_auto();
	const ucl_object_t *cur, *seq;
	ucl_object_iter_t it = NULL, itseq = NULL;
	struct config_entry *temp_config;
	struct config_value *cv;
	const char *key;
	int i;
	size_t j;

	/* Temporary config for configs that may be disabled. */
	temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry));

	while ((cur = ucl_iterate_object(obj, &it, true))) {
		key = ucl_object_key(cur);
		if (key == NULL)
			continue;
		sbuf_clear(buf);

		if (conftype == CONFFILE_PKG) {
			for (j = 0; j < strlen(key); ++j)
				sbuf_putc(buf, key[j]);
			sbuf_finish(buf);
		} else if (conftype == CONFFILE_REPO) {
			if (strcasecmp(key, "url") == 0)
				sbuf_cpy(buf, "PACKAGESITE");
			else if (strcasecmp(key, "mirror_type") == 0)
				sbuf_cpy(buf, "MIRROR_TYPE");
			else if (strcasecmp(key, "signature_type") == 0)
				sbuf_cpy(buf, "SIGNATURE_TYPE");
			else if (strcasecmp(key, "fingerprints") == 0)
				sbuf_cpy(buf, "FINGERPRINTS");
			else if (strcasecmp(key, "enabled") == 0) {
				if ((cur->type != UCL_BOOLEAN) ||
				    !ucl_object_toboolean(cur))
					goto cleanup;
			} else
				continue;
			sbuf_finish(buf);
		}

		for (i = 0; i < CONFIG_SIZE; i++) {
			if (strcmp(sbuf_data(buf), c[i].key) == 0)
				break;
		}

		/* Silently skip unknown keys to be future compatible. */
		if (i == CONFIG_SIZE)
			continue;

		/* env has priority over config file */
		if (c[i].envset)
			continue;

		/* Parse sequence value ["item1", "item2"] */
		switch (c[i].type) {
		case PKG_CONFIG_LIST:
			if (cur->type != UCL_ARRAY) {
				warnx("Skipping invalid array "
				    "value for %s.\n", c[i].key);
				continue;
			}
			temp_config[i].list =
			    malloc(sizeof(*temp_config[i].list));
			STAILQ_INIT(temp_config[i].list);

			while ((seq = ucl_iterate_object(cur, &itseq, true))) {
				if (seq->type != UCL_STRING)
					continue;
				cv = malloc(sizeof(struct config_value));
				cv->value =
				    strdup(ucl_object_tostring(seq));
				STAILQ_INSERT_TAIL(temp_config[i].list, cv,
				    next);
			}
			break;
		case PKG_CONFIG_BOOL:
			temp_config[i].value =
			    strdup(ucl_object_toboolean(cur) ? "yes" : "no");
			break;
		default:
			/* Normal string value. */
			temp_config[i].value = strdup(ucl_object_tostring(cur));
			break;
		}
	}

	/* Repo is enabled, copy over all settings from temp_config. */
	for (i = 0; i < CONFIG_SIZE; i++) {
		if (c[i].envset)
			continue;
		/* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */
		if (conftype != CONFFILE_PKG && c[i].main_only == true)
			continue;
		switch (c[i].type) {
		case PKG_CONFIG_LIST:
			c[i].list = temp_config[i].list;
			break;
		default:
			c[i].value = temp_config[i].value;
			break;
		}
	}

cleanup:
	free(temp_config);
	sbuf_delete(buf);
}
Esempio n. 21
0
File: query.c Progetto: afb/pkgng
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
	char size[7];
	const char *tmp;
	bool tmp2;
	int64_t flatsize;
	int64_t timestamp;
	lic_t licenselogic;

	sbuf_clear(dest);

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

	debug = 0;
	magic = '%';		/* Default magic char is `%'. */
	nargs = -1;
	while ((ch = getopt(argc, argv, "a:d0123456789")) != -1)
		switch (ch) {
		case 'a':
			if (optarg[1] != '\0')
				errx(1,
				    "illegal magic character specification");
			magic = optarg[0];
			break;
		case 'd':
			debug = 1;
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			if (nargs != -1)
				errx(1,
				    "only one -# argument may be specified");
			nargs = optopt - '0';
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 2)
		usage();

	/*
	 * The command to run is argv[0], and the args are argv[1..].
	 * Look for %digit references in the command, remembering the
	 * largest one.
	 */
	for (n = 0, p = argv[0]; *p != '\0'; ++p)
		if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
			++p;
			if (p[0] - '0' > n)
				n = p[0] - '0';
		}

	/*
	 * Figure out the shell and name arguments to pass to execl()
	 * in exec_shell().  Always malloc() shell and just set name
	 * to point at the last part of shell if there are any backslashes,
	 * otherwise just set it to point at the space malloc()'d.  If
	 * SHELL environment variable exists, replace contents of
	 * shell with it.
	 */
	shell = name = NULL;
	tmpshell = getenv("SHELL");
	shell = (tmpshell != NULL) ? strdup(tmpshell) : strdup(_PATH_BSHELL);
	if (shell == NULL)
		err(1, "strdup() failed");
	slashp = strrchr(shell, '/');
	name = (slashp != NULL) ? slashp + 1 : shell;

	/*
	 * If there were any %digit references, then use those, otherwise
	 * build a new command string with sufficient %digit references at
	 * the end to consume (nargs) arguments each time round the loop.
	 * Allocate enough space to hold the maximum command.  Save the
	 * size to pass to snprintf().
	 */
	cmdsize = sizeof(EXEC) - 1 + strlen(argv[0])
	    + 9 * (sizeof(" %1") - 1) + 1;
	if ((cmd = malloc(cmdsize)) == NULL)
		err(1, NULL);

	if (n == 0) {
		/* If nargs not set, default to a single argument. */
		if (nargs == -1)
			nargs = 1;

		p = cmd;
		offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
		if ((size_t)offset >= cmdsize)
			errx(1, "snprintf() failed");
		p += offset;
		cmdsize -= offset;
		for (i = 1; i <= nargs; i++) {
			offset = snprintf(p, cmdsize, " %c%d", magic, i);
			if ((size_t)offset >= cmdsize)
				errx(1, "snprintf() failed");
			p += offset;
			cmdsize -= offset;
		}

		/*
		 * If nargs set to the special value 0, eat a single
		 * argument for each command execution.
		 */
		if (nargs == 0)
			nargs = 1;
	} else {
		offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
		if ((size_t)offset >= cmdsize)
			errx(1, "snprintf() failed");
		nargs = n;
	}

	cmdbuf = sbuf_new(NULL, NULL, 1024, SBUF_AUTOEXTEND);
	if (cmdbuf == NULL)
		err(1, NULL);

	arg_max = sysconf(_SC_ARG_MAX);

	/*
	 * (argc) and (argv) are still offset by one to make it simpler to
	 * expand %digit references.  At the end of the loop check for (argc)
	 * equals 1 means that all the (argv) has been consumed.
	 */
	for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
		sbuf_clear(cmdbuf);
		/* Expand command argv references. */
		for (p = cmd; *p != '\0'; ++p) {
			if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
				if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0'])
				    == -1)
					errc(1, ENOMEM, "sbuf");
			} else {
				if (sbuf_putc(cmdbuf, *p) == -1)
					errc(1, ENOMEM, "sbuf");
			}
			if (sbuf_len(cmdbuf) > arg_max)
				errc(1, E2BIG, NULL);
		}

		/* Terminate the command string. */
		sbuf_finish(cmdbuf);

		/* Run the command. */
		if (debug)
			(void)printf("%s\n", sbuf_data(cmdbuf));
		else
			if (exec_shell(sbuf_data(cmdbuf), shell, name))
				rval = 1;
	}

	if (argc != 1)
		errx(1, "expecting additional argument%s after \"%s\"",
		    (nargs - argc) ? "s" : "", argv[argc - 1]);
	free(cmd);
	sbuf_delete(cmdbuf);
	free(shell);
	exit(rval);
}
Esempio n. 23
0
/* mtree_resolve() sets errno to indicate why NULL was returned. */
static char *
mtree_resolve(const char *spec, int *istemp)
{
	struct sbuf *sb;
	char *res, *var;
	const char *base, *p, *v;
	size_t len;
	int c, error, quoted, subst;

	len = strlen(spec);
	if (len == 0) {
		errno = EINVAL;
		return (NULL);
	}

	c = (len > 1) ? (spec[0] == spec[len - 1]) ? spec[0] : 0 : 0;
	*istemp = (c == '`') ? 1 : 0;
	subst = (c == '`' || c == '"') ? 1 : 0;
	quoted = (subst || c == '\'') ? 1 : 0;

	if (!subst) {
		res = strdup(spec + quoted);
		if (res != NULL && quoted)
			res[len - 2] = '\0';
		return (res);
	}

	sb = sbuf_new_auto();
	if (sb == NULL) {
		errno = ENOMEM;
		return (NULL);
	}

	base = spec + 1;
	len -= 2;
	error = 0;
	while (len > 0) {
		p = strchr(base, '$');
		if (p == NULL) {
			sbuf_bcat(sb, base, len);
			base += len;
			len = 0;
			continue;
		}
		/* The following is safe. spec always starts with a quote. */
		if (p[-1] == '\\')
			p--;
		if (base != p) {
			sbuf_bcat(sb, base, p - base);
			len -= p - base;
			base = p;
		}
		if (*p == '\\') {
			sbuf_putc(sb, '$');
			base += 2;
			len -= 2;
			continue;
		}
		/* Skip the '$'. */
		base++;
		len--;
		/* Handle ${X} vs $X. */
		v = base;
		if (*base == '{') {
			p = strchr(v, '}');
			if (p == NULL)
				p = v;
		} else
			p = v;
		len -= (p + 1) - base;
		base = p + 1;

		if (v == p) {
			sbuf_putc(sb, *v);
			continue;
		}

		error = ENOMEM;
		var = calloc(p - v, 1);
		if (var == NULL)
			break;

		memcpy(var, v + 1, p - v - 1);
		if (strcmp(var, ".CURDIR") == 0) {
			res = getcwd(NULL, 0);
			if (res == NULL)
				break;
		} else if (strcmp(var, ".PROG") == 0) {
			res = strdup(getprogname());
			if (res == NULL)
				break;
		} else {
			v = getenv(var);
			if (v != NULL) {
				res = strdup(v);
				if (res == NULL)
					break;
			} else
				res = NULL;
		}
		error = 0;

		if (res != NULL) {
			sbuf_cat(sb, res);
			free(res);
		}
		free(var);
	}

	sbuf_finish(sb);
	res = (error == 0) ? strdup(sbuf_data(sb)) : NULL;
	sbuf_delete(sb);
	if (res == NULL)
		errno = ENOMEM;
	return (res);
}
Esempio n. 24
0
static int
scan(FILE *fp, const char *name, bool quiet)
{
	int c;
	bool hasid = false;
	bool subversion = false;
	analyzer_states state = INIT;
	struct sbuf *id = sbuf_new_auto();
	locale_t l;

	l = newlocale(LC_ALL_MASK, "C", NULL);

	if (name != NULL)
		printf("%s:\n", name);

	while ((c = fgetc(fp)) != EOF) {
		switch (state) {
		case INIT:
			if (c == '$') {
				/* Transit to DELIM_SEEN if we see $ */
				state = DELIM_SEEN;
			} else {
				/* Otherwise, stay in INIT state */
				continue;
			}
			break;
		case DELIM_SEEN:
			if (isalpha_l(c, l)) {
				/* Transit to KEYWORD if we see letter */
				sbuf_clear(id);
				sbuf_putc(id, '$');
				sbuf_putc(id, c);
				state = KEYWORD;

				continue;
			} else if (c == '$') {
				/* Or, stay in DELIM_SEEN if more $ */
				continue;
			} else {
				/* Otherwise, transit back to INIT */
				state = INIT;
			}
			break;
		case KEYWORD:
			sbuf_putc(id, c);

			if (isalpha_l(c, l)) {
				/*
				 * Stay in KEYWORD if additional letter is seen
				 */
				continue;
			} else if (c == ':') {
				/*
				 * See ':' for the first time, transit to
				 * PUNC_SEEN.
				 */
				state = PUNC_SEEN;
				subversion = false;
			} else if (c == '$') {
				/*
				 * Incomplete ident.  Go back to DELIM_SEEN
				 * state because we see a '$' which could be
				 * the beginning of a keyword.
				 */
				state = DELIM_SEEN;
			} else {
				/*
				 * Go back to INIT state otherwise.
				 */
				state = INIT;
			}
			break;
		case PUNC_SEEN:
		case PUNC_SEEN_SVN:
			sbuf_putc(id, c);

			switch (c) {
			case ':':
				/*
				 * If we see '::' (seen : in PUNC_SEEN),
				 * activate subversion treatment and transit
				 * to PUNC_SEEN_SVN state.
				 *
				 * If more than two :'s were seen, the ident
				 * is invalid and we would therefore go back
				 * to INIT state.
				 */
				if (state == PUNC_SEEN) {
					state = PUNC_SEEN_SVN;
					subversion = true;
				} else {
					state = INIT;
				}
				break;
			case ' ':
				/*
				 * A space after ':' or '::' indicates we are at the
				 * last component of potential ident.
				 */
				state = TEXT;
				break;
			default:
				/* All other characters are invalid */
				state = INIT;
				break;
			}
			break;
		case TEXT:
			sbuf_putc(id, c);

			if (iscntrl_l(c, l)) {
				/* Control characters are not allowed in this state */
				state = INIT;
			} else if (c == '$') {
				sbuf_finish(id);
				/*
				 * valid ident should end with a space.
				 *
				 * subversion extension uses '#' to indicate that
				 * the keyword expansion have exceeded the fixed
				 * width, so it is also permitted if we are in
				 * subversion mode.  No length check is enforced
				 * because GNU RCS ident(1) does not do it either.
				 */
				c = sbuf_data(id)[sbuf_len(id) - 2];
				if (c == ' ' || (subversion && c == '#')) {
					printf("     %s\n", sbuf_data(id));
					hasid = true;
				}
				state = INIT;
			}
			/* Other characters: stay in the state */
			break;
		}
	}
	sbuf_delete(id);
	freelocale(l);

	if (!hasid) {
		if (!quiet)
			fprintf(stderr, "%s warning: no id keywords in %s\n",
			    getprogname(), name ? name : "standard input");

		return (EXIT_FAILURE);
	}

	return (EXIT_SUCCESS);
}