Exemplo n.º 1
0
/*
 * Quote/unquote a string using shell style quoting
 */
char *
ni_quote(const char *string, const char *sepa)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	unsigned int n, m;
	int cc;

	if (sepa)
		m = strcspn(string, sepa);
	else
		m = strlen(string);

	n = strcspn(string, "\"'");
	if (m == n && string[n] == '\0')
		return xstrdup(string);

	ni_stringbuf_putc(&buf, '"');
	while ((cc = *string++) != '\0') {
		if (cc == '"' || cc == '\'' || cc == '\\')
			ni_stringbuf_putc(&buf, '\\');
		ni_stringbuf_putc(&buf, cc);
	}
	ni_stringbuf_putc(&buf, '"');
	return buf.string;
}
Exemplo n.º 2
0
static char *
__xpath_node_array_print_short(const xpath_result_t *na)
{
	ni_stringbuf_t buf;
	unsigned int n;

	if (na->type == XPATH_BOOLEAN)
		return xstrdup(__xpath_test_boolean(na)? "[true]" : "[false]");

	if (na->count == 0)
		return xstrdup("[]");

	ni_stringbuf_init(&buf);
	ni_stringbuf_putc(&buf, '[');

	for (n = 0; n < na->count; ++n) {
		const char *string;

		if (n)
			ni_stringbuf_puts(&buf, ", ");
		if (n >= 7) {
			ni_stringbuf_puts(&buf, "...");
			break;
		}

		switch (na->type) {
		case XPATH_ELEMENT:
			string = na->node[n].value.node->name;
			ni_stringbuf_printf(&buf, "<%s>", string?: "ROOT");
			break;

		case XPATH_INTEGER:
			ni_stringbuf_printf(&buf, "%ld", na->node[n].value.integer);
			break;

		case XPATH_STRING:
			string = na->node[n].value.string;
			if (strlen(string) > 32)
				ni_stringbuf_printf(&buf, "\"%.32s ...\"", string);
			else
				ni_stringbuf_printf(&buf, "\"%s\"", string);
			break;

		default:
			ni_stringbuf_puts(&buf, "???");
		}
	}

	ni_stringbuf_putc(&buf, ']');
	return buf.string;
}
Exemplo n.º 3
0
/*
 * Expand an XML entity.
 * For now, we support &<number>; as well as symbolic entities
 *   lt gt amp
 */
ni_bool_t
xml_expand_entity(xml_reader_t *xr, ni_stringbuf_t *res)
{
	char temp[128];
	ni_stringbuf_t entity = NI_STRINGBUF_INIT_BUFFER(temp);
	int cc, expanded;

	while ((cc = xml_getc(xr)) != ';') {
		if (cc == EOF) {
			xml_parse_error(xr, "Unexpenced EOF in entity");
			return FALSE;
		}
		if (isspace(cc))
			continue;
		if (entity.len + sizeof(char) >= entity.size) {
			xml_parse_error(xr, "Entity is too long");
			return FALSE;
		}
		ni_stringbuf_putc(&entity, cc);
	}

	if (ni_string_empty(entity.string)) {
		xml_parse_error(xr, "Empty entity &;");
		return FALSE;
	}

	if (!strcasecmp(entity.string, "lt"))
		expanded = '<';
	else if (!strcasecmp(entity.string, "gt"))
		expanded = '>';
	else if (!strcasecmp(entity.string, "amp"))
		expanded = '&';
	else {
		const char *es = entity.string;

		if (*es == '#') {
			expanded = strtoul(es + 1, (char **) &es, 0);
			if (*es == '\0')
				goto good;
		}

		xml_parse_error(xr, "Cannot expand unknown entity &%s;", entity.string);
		return FALSE;
	}

good:
	ni_stringbuf_putc(res, expanded);
	return TRUE;
}
Exemplo n.º 4
0
char *
ni_unquote(const char **stringp, const char *sepa)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	const char *src = *stringp;
	int cc;

	if (sepa)
		src += strspn(src, sepa);

	while ((cc = *src) != '\0') {
		++src;
		if (sepa && strchr(sepa, cc))
			break;
		if (cc == '"') {
			while ((cc = *src++) != '"') {
				if (cc == '\0')
					goto failed;
				if (cc == '\\') {
					cc = *src++;
					if (cc == '\0')
						goto failed;
				}
				ni_stringbuf_putc(&buf, cc);
			}
		} else if (cc == '\'') {
			while ((cc = *src++) != '\'') {
				if (cc == '\0')
					goto failed;
				ni_stringbuf_putc(&buf, cc);
			}
		} else {
			ni_stringbuf_putc(&buf, cc);
		}
	}

	*stringp = src;
	return buf.string;

failed:
	ni_stringbuf_destroy(&buf);
	return NULL;
}
Exemplo n.º 5
0
/*
 * Skip any space in the input stream, and copy if to @result
 */
void
xml_skip_space(xml_reader_t *xr, ni_stringbuf_t *result)
{
	int cc;

	while ((cc = xml_getc(xr)) != EOF) {
		if (!isspace(cc)) {
			xml_ungetc(xr, cc);
			break;
		}

		if (result)
			ni_stringbuf_putc(result, cc);
	}
}
Exemplo n.º 6
0
Arquivo: main.c Projeto: kmroz/wicked
static void
show_exec_info(int argc, char **argv)
{
	ni_stringbuf_t args = NI_STRINGBUF_INIT_DYNAMIC;
	int i;

	for (i = 0; i < argc && argv[i]; ++i) {
		if (i != 0)
			ni_stringbuf_putc(&args, ' ');
		ni_stringbuf_puts(&args, argv[i]);
	}

	ni_debug_application("Executing: %s", args.string);
	ni_stringbuf_destroy(&args);
}
Exemplo n.º 7
0
xml_token_type_t
xml_get_token_tag(xml_reader_t *xr, ni_stringbuf_t *res)
{
	int cc, oc;

	xml_skip_space(xr, NULL);

	cc = xml_getc(xr);
	if (cc == EOF) {
		xml_parse_error(xr, "Unexpected EOF while parsing tag");
		return None;
	}

	ni_stringbuf_putc(res, cc);

	switch (cc) {
	case '<':
		goto error;

	case '?':
		if ((cc = xml_getc(xr)) != '>')
			goto error;
		ni_stringbuf_putc(res, cc);
		xr->state = Initial;
		return RightAngleQ;

	case '>':
		xr->state = Initial;
		return RightAngle;

	case '/':
		if ((cc = xml_getc(xr)) != '>')
			goto error;
		ni_stringbuf_putc(res, cc);
		xr->state = Initial;
		return RightAngleSlash;

	case '=':
		return Equals;

	case 'a' ... 'z':
	case 'A' ... 'Z':
	case '_':
	case '!':
		while ((cc = xml_getc(xr)) != EOF) {
			if (!isalnum(cc) && cc != '_' && cc != '!' && cc != ':' && cc != '-') {
				xml_ungetc(xr, cc);
				break;
			}
			ni_stringbuf_putc(res, cc);
		}
		return Identifier;

	case '\'':
	case '"':
		ni_stringbuf_clear(res);
		oc = cc;
		while (1) {
			cc = xml_getc(xr);
			if (cc == EOF) {
				xml_parse_error(xr, "Unexpected EOF while parsing quoted string");
				return None;
			}
			if (cc == oc)
				break;
			ni_stringbuf_putc(res, cc);
		}
		return QuotedString;

	default:
		break;
	}

error:
	xml_parse_error(xr, "Unexpected character %c in XML document", cc);
	return None;
}
Exemplo n.º 8
0
/*
 * While in state Initial, obtain the next token
 */
xml_token_type_t
xml_get_token_initial(xml_reader_t *xr, ni_stringbuf_t *res)
{
	xml_token_type_t token;
	int cc;

restart:
	/* Eat initial white space and store it in @res */
	xml_skip_space(xr, res);

	cc = xml_getc(xr);
	if (cc == EOF) {
		ni_stringbuf_clear(res);
		return EndOfDocument;
	}

	if (cc == '<') {
		/* Discard the white space in @res - we're not interested in that. */
		ni_stringbuf_clear(res);

		ni_stringbuf_putc(res, cc);

		if (xr->state != Initial) {
			xml_parse_error(xr, "Unexpected < in XML stream (state %s)",
					xml_parser_state_name(xr->state));
			return None;
		}

		/* tag is legal here */
		xr->state = Tag;

		cc = xml_getc(xr);
		switch (cc) {
		case '/':
			ni_stringbuf_putc(res, cc);
			return LeftAngleSlash;
		case '?':
			ni_stringbuf_putc(res, cc);
			return LeftAngleQ;
		case '!':
			ni_stringbuf_putc(res, cc);

			/* If it's <!IDENTIFIER, return LeftAngleExclam */
			cc = xml_getc(xr);
			if (cc != '-') {
				xml_ungetc(xr, cc);
				return LeftAngleExclam;
			}

			token = xml_skip_comment(xr);
			if (token == Comment) {
				xr->state = Initial;
				ni_stringbuf_clear(res);
				goto restart;
			}
			return token;
		default:
			xml_ungetc(xr, cc);
			break;
		}
		return LeftAngle;
	}

	// Looks like CDATA. 
	// Ignore initial newline, then scan to next <
	do {
		if (cc == '<') {
			/* Looks like we're done.
			 * FIXME: handle comments within CDATA?
			 */
			xml_ungetc(xr, cc);
			break;
		} else
		if (cc == '&') {
			if (!xml_expand_entity(xr, res))
				return None;
		} else {
			ni_stringbuf_putc(res, cc);
		}

		cc = xml_getc(xr);
	} while (cc != EOF);

	ni_stringbuf_trim_empty_lines(res);

	return CData;
}
Exemplo n.º 9
0
/*
 * Decode an RFC3397 DNS search order option.
 */
static int
ni_dhcp_decode_dnssearch(ni_buffer_t *optbuf, ni_string_array_t *list, const char *what)
{
	ni_stringbuf_t namebuf = NI_STRINGBUF_INIT_DYNAMIC;
	unsigned char *base = ni_buffer_head(optbuf);
	unsigned int base_offset = optbuf->head;
	size_t len;

	ni_string_array_destroy(list);

	while (ni_buffer_count(optbuf) && !optbuf->underflow) {
		ni_buffer_t *bp = optbuf;
		ni_buffer_t jumpbuf;

		while (1) {
			unsigned int pos = bp->head - base_offset;
			unsigned int pointer;
			char label[64];
			int length;

			if ((length = ni_buffer_getc(bp)) < 0)
				goto failure; /* unexpected EOF */

			if (length == 0)
				break;	/* end of this name */

			switch (length & 0xC0) {
			case 0:
				/* Plain name component */
				if (ni_buffer_get(bp, label, length) < 0)
					goto failure;

				label[length] = '\0';
				if (!ni_stringbuf_empty(&namebuf))
					ni_stringbuf_putc(&namebuf, '.');
				ni_stringbuf_puts(&namebuf, label);
				break;

			case 0xC0:
				/* Pointer */
				pointer = (length & 0x3F) << 8;
				if ((length = ni_buffer_getc(bp)) < 0)
					goto failure;

				pointer |= length;
				if (pointer >= pos)
					goto failure;

				ni_buffer_init_reader(&jumpbuf, base, pos);
				jumpbuf.head = pointer;
				bp = &jumpbuf;
				break;

			default:
				goto failure;
			}

		}

		if (!ni_stringbuf_empty(&namebuf)) {

			len = ni_string_len(namebuf.string);
			if (ni_check_domain_name(namebuf.string, len, 0)) {
				ni_string_array_append(list, namebuf.string);
			} else {
				ni_debug_dhcp("Discarded suspect %s: %s", what,
					ni_print_suspect(namebuf.string, len));
			}
		}
		ni_stringbuf_destroy(&namebuf);
	}

	return 0;

failure:
	ni_stringbuf_destroy(&namebuf);
	ni_string_array_destroy(list);
	return -1;
}