Ejemplo n.º 1
0
ACL_VSTRING *escape(ACL_VSTRING *result, const char *data, ssize_t len)
{
	int     ch;

	ACL_VSTRING_RESET(result);
	while (len-- > 0) {
		ch = *UCHAR(data++);
		if (ACL_ISASCII(ch)) {
			if (ACL_ISPRINT(ch)) {
				if (ch == '\\')
					ACL_VSTRING_ADDCH(result, ch);
				ACL_VSTRING_ADDCH(result, ch);
				continue;
			} else if (ch == '\a') {		/* \a -> audible bell */
				acl_vstring_strcat(result, "\\a");
				continue;
			} else if (ch == '\b') {		/* \b -> backspace */
				acl_vstring_strcat(result, "\\b");
				continue;
			} else if (ch == '\f') {		/* \f -> formfeed */
				acl_vstring_strcat(result, "\\f");
				continue;
			} else if (ch == '\n') {		/* \n -> newline */
				acl_vstring_strcat(result, "\\n");
				continue;
			} else if (ch == '\r') {		/* \r -> carriagereturn */
				acl_vstring_strcat(result, "\\r");
				continue;
			} else if (ch == '\t') {		/* \t -> horizontal tab */
				acl_vstring_strcat(result, "\\t");
				continue;
			} else if (ch == '\v') {		/* \v -> vertical tab */
				acl_vstring_strcat(result, "\\v");
				continue;
			}
		}
		if (ACL_ISDIGIT(*UCHAR(data)))
			acl_vstring_sprintf_append(result, "\\%03d", ch);
		else
			acl_vstring_sprintf_append(result, "\\%d", ch);
	}
	ACL_VSTRING_TERMINATE(result);
	return (result);
}
Ejemplo n.º 2
0
static const char *xml_meta_attr_value(ACL_XML_ATTR *attr, const char *data)
{
	int   ch;

	SKIP_SPACE(data);
	if (*data == 0)
		return data;
	if (IS_QUOTE(*data))
		attr->quote = *data++;

	while ((ch = *data) != 0) {
		if (attr->backslash) {
			ACL_VSTRING_ADDCH(attr->value, ch);
			attr->backslash = 0;
		} else if (ch == '\\') {
			if (attr->part_word) {
				ACL_VSTRING_ADDCH(attr->value, ch);
				attr->part_word = 0;
			} else
				attr->backslash = 1;
		} else if (attr->quote) {
			if (ch == attr->quote) {
				data++;
				break;
			}
			ACL_VSTRING_ADDCH(attr->value, ch);
		} else if (IS_SPACE(ch)) {
			data++;
			break;
		} else {
			ACL_VSTRING_ADDCH(attr->value, ch);
			if ((attr->node->xml->flag & ACL_XML_FLAG_PART_WORD)) {
				if (attr->part_word)
					attr->part_word = 0;
				else if (ch < 0)
					attr->part_word = 1;
			}
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(attr->value);
	return data;
}
Ejemplo n.º 3
0
static void acl_token_name_walk(const ACL_TOKEN *token, void *arg)
{
	ACL_VSTRING *buf = (ACL_VSTRING*) arg;
	ACL_VSTRING *name = acl_vstring_alloc(256);

	acl_token_name(token, name);
	if (LEN(buf) > 0)
		ACL_VSTRING_ADDCH(buf, ';');
	acl_vstring_strcat(buf, STR(name));
	acl_vstring_free(name);
}
Ejemplo n.º 4
0
static void strip_address(ACL_VSTRING *vp, ssize_t start, TOK822 *addr)
{
	ACL_VSTRING *tmp;

	/*
	 * Emit plain <address>. Discard any comments or phrases.
	 */
	ACL_VSTRING_TERMINATE(vp);
	acl_msg_warn("stripping too many comments from address: %.100s...",
			acl_vstring_str(vp) + start);
	//acl_printable(vstring_str(vp) + start, '?')); //zsx
	acl_vstring_truncate(vp, start);
	ACL_VSTRING_ADDCH(vp, '<');
	if (addr) {
		tmp = acl_vstring_alloc(100);
		tok822_internalize(tmp, addr, TOK822_STR_TERM);
		quote_822_local_flags(vp, acl_vstring_str(tmp),
			QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_APPEND);
		acl_vstring_free(tmp);
	}
	ACL_VSTRING_ADDCH(vp, '>');
}
Ejemplo n.º 5
0
ACL_VSTRING *acl_hex_encode(ACL_VSTRING *result, const char *in, int len)
{
	const unsigned char *cp;
	int     ch;
	int     count;

	ACL_VSTRING_RESET(result);
	for (cp = UCHAR_PTR(in), count = len; count > 0; count--, cp++) {
		ch = *cp;
		ACL_VSTRING_ADDCH(result, acl_hex_chars[(ch >> 4) & 0xf]);
		ACL_VSTRING_ADDCH(result, acl_hex_chars[ch & 0xf]);
	}
	ACL_VSTRING_TERMINATE(result);
	return (result);
}
Ejemplo n.º 6
0
static const char *xml_parse_right_lt(ACL_XML *xml, const char *data)
{
	ACL_XML_NODE *node;

	SKIP_SPACE(data);
	if (*data == 0)
		return (NULL);
	if (*data == '/') {
		xml->curr_node->status = ACL_XML_S_RTAG;
		data++;
		return (data);
	} else if ((xml->curr_node->flag & ACL_XML_F_LEAF)) {
		ACL_VSTRING_ADDCH(xml->curr_node->text, '<');
		ACL_VSTRING_ADDCH(xml->curr_node->text, *data);
		ACL_VSTRING_TERMINATE(xml->curr_node->text);
		xml->curr_node->status = ACL_XML_S_TXT;
		data++;
		return (data);
	}

	/* 说明遇到了当前结点的子结点 */

	/* 重新设置当前结点状态,以便于其可以找到 "</" */
	xml->curr_node->status = ACL_XML_S_TXT;

	/* 创建新的子结点,并将其加入至当前结点的子结点集合中 */

	node = acl_xml_node_alloc(xml);
	acl_xml_node_add_child(xml->curr_node, node);
	node->depth = xml->curr_node->depth + 1;
	if (node->depth > xml->depth)
		xml->depth = node->depth;
	xml->curr_node = node;
	xml->curr_node->status = ACL_XML_S_LLT;
	return (data);
}
Ejemplo n.º 7
0
static const char *xml_parse_meta_tag(ACL_XML *xml, const char *data)
{
	int   ch;

	while ((ch = *data) != 0) {
		data++;
		if (IS_SPACE(ch)) {
			xml->curr_node->status = ACL_XML_S_MTXT;
			break;
		}
		ACL_VSTRING_ADDCH(xml->curr_node->ltag, ch);
	}
	ACL_VSTRING_TERMINATE(xml->curr_node->ltag);
	return (data);
}
Ejemplo n.º 8
0
static const char *xml_parse_attr(ACL_XML *xml, const char *data)
{
	int   ch;
	ACL_XML_ATTR *attr = xml->curr_node->curr_attr;

	if (attr == NULL || LEN(attr->name) == 0) {
		SKIP_SPACE(data);	/* 略过 ' ', '\t' */
		if (*data == 0)
			return (NULL);
		SKIP_WHILE(*data == '=', data);
		if (*data == 0)
			return (NULL);
	}

	if (*data == '>') {
		xml->curr_node->status = ACL_XML_S_LGT;
		xml_parse_check_self_closed(xml);
		xml->curr_node->curr_attr = NULL;
		data++;
		return (data);
	}

	xml->curr_node->last_ch = *data;
	if (*data == '/') {
		data++;
		return (data);
	}

	if (attr == NULL) {
		attr = acl_xml_attr_alloc(xml->curr_node);
		xml->curr_node->curr_attr = attr;
	}

	while ((ch = *data) != 0) {
		xml->curr_node->last_ch = ch;
		if (ch == '=') {
			xml->curr_node->status = ACL_XML_S_AVAL;
			data++;
			break;
		}
		if (!IS_SPACE(ch))
			ACL_VSTRING_ADDCH(attr->name, ch);
		data++;
	}

	ACL_VSTRING_TERMINATE(attr->name);
	return (data);
}
Ejemplo n.º 9
0
static const char *xml_meta_attr_name(ACL_XML_ATTR *attr, const char *data)
{
	int   ch;

	while ((ch = *data) != 0) {
		if (ch == '=') {
			data++;
			ACL_VSTRING_TERMINATE(attr->name);
			break;
		}
		if (!IS_SPACE(ch))
			ACL_VSTRING_ADDCH(attr->name, ch);
		data++;
	}
	return data;
}
Ejemplo n.º 10
0
int acl_xml_encode(const char *in, ACL_VSTRING *out)
{
    int  n = 0;

    while (*in) {
        if (__charmap[(unsigned char)(*in)] != NULL) {
            acl_vstring_strcat(out,
                               __charmap[(unsigned char)(*in)]);
            n++;
        } else
            ACL_VSTRING_ADDCH(out, (*in));
        in++;
    }

    ACL_VSTRING_TERMINATE(out);
    return (n);
}
Ejemplo n.º 11
0
ACL_VSTRING *tok822_internalize(ACL_VSTRING *vp, TOK822 *tree, int flags)
{
	TOK822 *tp;

	if (flags & TOK822_STR_WIPE)
		ACL_VSTRING_RESET(vp);

	for (tp = tree; tp; tp = tp->next) {
		switch (tp->type) {
		case ',':
			ACL_VSTRING_ADDCH(vp, tp->type);
			if (flags & TOK822_STR_LINE) {
				ACL_VSTRING_ADDCH(vp, '\n');
				continue;
			}
			break;
		case TOK822_ADDR:
			tok822_internalize(vp, tp->head, TOK822_STR_NONE);
			break;
		case TOK822_COMMENT:
		case TOK822_ATOM:
		case TOK822_QSTRING:
			acl_vstring_strcat(vp, acl_vstring_str(tp->vstr));
			break;
		case TOK822_DOMLIT:
			ACL_VSTRING_ADDCH(vp, '[');
			acl_vstring_strcat(vp, acl_vstring_str(tp->vstr));
			ACL_VSTRING_ADDCH(vp, ']');
			break;
		case TOK822_STARTGRP:
			ACL_VSTRING_ADDCH(vp, ':');
			break;
		default:
			if (tp->type >= TOK822_MINTOK)
				acl_msg_panic("tok822_internalize: unknown operator %d", tp->type);
			ACL_VSTRING_ADDCH(vp, tp->type);
		}
		if (tok822_append_space(tp))
			ACL_VSTRING_ADDCH(vp, ' ');
	}
	if (flags & TOK822_STR_TERM)
		ACL_VSTRING_TERMINATE(vp);
	return (vp);
}
Ejemplo n.º 12
0
static const char *xml_parse_text(ACL_XML *xml, const char *data)
{
	int   ch;

	if (LEN(xml->curr_node->text) == 0) {
		SKIP_SPACE(data);
		if (*data == 0)
			return (NULL);
	}

	while ((ch = *data) != 0) {
		if (ch == '<') {
			xml->curr_node->status = ACL_XML_S_RLT;
			data++;
			break;
		}
		ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		data++;
	}

	ACL_VSTRING_TERMINATE(xml->curr_node->text);

	if (xml->curr_node->status != ACL_XML_S_RLT)
		return (data);

	if ((xml->curr_node->flag & ACL_XML_F_SELF_CL)) {
		/* 如果该标签是自关闭类型,则应使父结点直接跳至右边 '/' 处理位置,
		 * 同时使本结点跳至右边 '>' 处理位置
		 */
		ACL_XML_NODE *parent = acl_xml_node_parent(xml->curr_node);
		if (parent != xml->root)
			parent->status = ACL_XML_S_RLT;
		xml->curr_node->status = ACL_XML_S_RGT;
	}

	if (LEN(xml->curr_node->text) == 0)
		return (data);

	return (data);
}
Ejemplo n.º 13
0
int acl_xml_encode(const char *in, ACL_VSTRING *out)
{
    const unsigned char *ptr = (const unsigned char*) in;
    int  n = 0;
    size_t len = strlen(in);

    len += len / 2;

    ACL_VSTRING_SPACE(out, (int) len);

    while (*ptr) {
        if (__charmap[*ptr] != NULL) {
            acl_vstring_strcat(out, __charmap[*ptr]);
            n++;
        } else {
            ACL_VSTRING_ADDCH(out, *ptr);
        }
        ptr++;
    }

    ACL_VSTRING_TERMINATE(out);
    return n;
}
Ejemplo n.º 14
0
static const char *xml_parse_meta_comment(ACL_XML *xml, const char *data)
{
	int   ch;

	if (LEN(xml->curr_node->text) == 0) {
		SKIP_SPACE(data);
	}

	while ((ch = *data) != 0) {
		if (xml->curr_node->quote) {
			if (ch == xml->curr_node->quote) {
				xml->curr_node->quote = 0;
			} else {
				ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
			}
		} else if (IS_QUOTE(ch)) {
			if (xml->curr_node->quote == 0) {
				xml->curr_node->quote = ch;
			} else {
				ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
			}
		} else if (ch == '<') {
			xml->curr_node->nlt++;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '>') {
			if (xml->curr_node->nlt == 0) {
				if (xml->curr_node->meta[0] == '-'
					&& xml->curr_node->meta[1] == '-')
				{
					data++;
					xml->curr_node->status = ACL_XML_S_MEND;
					break;
				}
			}
			xml->curr_node->nlt--;
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (xml->curr_node->nlt > 0) {
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		} else if (ch == '-') {
			if (xml->curr_node->meta[0] != '-') {
				xml->curr_node->meta[0] = '-';
			} else if (xml->curr_node->meta[1] != '-') {
				xml->curr_node->meta[1] = '-';
			}
		} else {
			if (xml->curr_node->meta[0] == '-') {
				ACL_VSTRING_ADDCH(xml->curr_node->text, '-');
				xml->curr_node->meta[0] = 0;
			}
			if (xml->curr_node->meta[1] == '-') {
				ACL_VSTRING_ADDCH(xml->curr_node->text, '-');
				xml->curr_node->meta[1] = 0;
			}
			ACL_VSTRING_ADDCH(xml->curr_node->text, ch);
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(xml->curr_node->text);
	return (data);
}
Ejemplo n.º 15
0
ssize_t header_token(HEADER_TOKEN *token, ssize_t token_len,
	ACL_VSTRING *token_buffer, const char **ptr,
	const char *user_specials, int user_terminator)
{
	ssize_t comment_level;
	const unsigned char *cp;
	ssize_t len;
	int     ch;
	ssize_t tok_count;
	ssize_t n;

	/*
	 * Initialize.
	 */
	ACL_VSTRING_RESET(token_buffer);
	cp = CU_CHAR_PTR(*ptr);
	tok_count = 0;
	if (user_specials == 0)
		user_specials = LEX_822_SPECIALS;

	/*
	 * Main parsing loop.
	 * 
	 * XXX What was the reason to continue parsing when user_terminator is
	 * specified? Perhaps this was needed at some intermediate stage of
	 * development?
	 */
	while ((ch = *cp) != 0 && (user_terminator != 0 || tok_count < token_len)) {
		cp++;

		/*
		 * Skip RFC 822 linear white space.
		 */
		if (IS_SPACE_TAB_CR_LF(ch))
			continue;

		/*
		 * Terminator.
		 */
		if (ch == user_terminator)
			break;

		/*
		 * Skip RFC 822 comment.
		 */
		if (ch == '(') {
			comment_level = 1;
			while ((ch = *cp) != 0) {
				cp++;
				if (ch == '(') {  /* comments can nest! */
					comment_level++;
				} else if (ch == ')') {
					if (--comment_level == 0)
						break;
				} else if (ch == '\\') {
					if ((ch = *cp) == 0)
						break;
					cp++;
				}
			}
			continue;
		}

		/*
		 * Copy quoted text according to RFC 822.
		 */
		if (ch == '"') {
			if (tok_count < token_len) {
				token[tok_count].u.offset = LEN(token_buffer);
				token[tok_count].type = HEADER_TOK_QSTRING;
			}
			while ((ch = *cp) != 0) {
				cp++;
				if (ch == '"')
					break;
				if (ch == '\n') {		/* unfold */
					if (tok_count < token_len) {
						len = LEN(token_buffer);
						while (len > 0 && IS_SPACE_TAB_CR_LF(STR(token_buffer)[len - 1]))
							len--;
						if (len < (ssize_t) LEN(token_buffer))
							acl_vstring_truncate(token_buffer, len);
					}
					continue;
				}
				if (ch == '\\') {
					if (tok_count < token_len)
						ACL_VSTRING_ADDCH(token_buffer, ch);

					if (*cp == 0)
						break;
					ch = *cp;
					cp++;
				}
				if (tok_count < token_len)
					ACL_VSTRING_ADDCH(token_buffer, ch);
			}
			if (tok_count < token_len) {
				ACL_VSTRING_ADDCH(token_buffer, 0);
				tok_count++;
			}
			continue;
		}

		/*
		 * Control, or special.
		 */
		if (strchr(user_specials, ch) || ACL_ISCNTRL(ch)) {
			if (tok_count < token_len) {
				token[tok_count].u.offset = LEN(token_buffer);
				token[tok_count].type = ch;
				ACL_VSTRING_ADDCH(token_buffer, ch);
				ACL_VSTRING_ADDCH(token_buffer, 0);
				tok_count++;
			}
			continue;
		}

		/*
		 * Token.
		 */
		else {
			if (tok_count < token_len) {
				token[tok_count].u.offset = LEN(token_buffer);
				token[tok_count].type = HEADER_TOK_TOKEN;
				ACL_VSTRING_ADDCH(token_buffer, ch);
			}
			while ((ch = *cp) != 0 && !IS_SPACE_TAB_CR_LF(ch)
				&& !ACL_ISCNTRL(ch) && !strchr(user_specials, ch)) {
					cp++;
					if (tok_count < token_len)
						ACL_VSTRING_ADDCH(token_buffer, ch);
				}
				if (tok_count < token_len) {
					ACL_VSTRING_ADDCH(token_buffer, 0);
					tok_count++;
				}
				continue;
		}
	}

	/*
	 * Ignore a zero-length item after the last terminator.
	 */
	if (tok_count == 0 && ch == 0)
		return (-1);

	/*
	 * Finalize. Fill in the string pointer array, now that the token buffer
	 * is no longer dynamically reallocated as it grows.
	 */
	*ptr = (const char *) cp;
	for (n = 0; n < tok_count; n++)
		token[n].u.value = STR(token_buffer) + token[n].u.offset;

	//if (acl_msg_verbose)
	//	acl_msg_info("header_token: %s %s %s",
	//		tok_count > 0 ? token[0].u.value : "",
	//		tok_count > 1 ? token[1].u.value : "",
	//		tok_count > 2 ? token[2].u.value : "");

	return (tok_count);
}
Ejemplo n.º 16
0
static const char *xml_parse_attr_val(ACL_XML *xml, const char *data)
{
	int   ch;
	ACL_XML_ATTR *attr = xml->curr_node->curr_attr;

	if (LEN(attr->value) == 0 && !attr->quote) {
		SKIP_SPACE(data);
		if (IS_QUOTE(*data)) {
			attr->quote = *data++;
		}
		if (*data == 0) {
			return (NULL);
		}
	}

	while ((ch = *data) != 0) {
		if (attr->backslash) {
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;
			attr->backslash = 0;
		} else if (ch == '\\') {
			if (attr->part_word) {
				ACL_VSTRING_ADDCH(attr->value, ch);
				attr->part_word = 0;
			}
			else
				attr->backslash = 1;
		} else if (attr->quote) {
			if (ch == attr->quote) {
				xml->curr_node->status = ACL_XML_S_ATTR;
				xml->curr_node->last_ch = ch;
				data++;
				break;
			}
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;
		} else if (ch == '>') {
			xml->curr_node->status = ACL_XML_S_LGT;
			xml_parse_check_self_closed(xml);
			data++;
			break;
		} else if (IS_SPACE(ch)) {
			xml->curr_node->status = ACL_XML_S_ATTR;
			xml->curr_node->last_ch = ch;
			data++;
			break;
		} else {
			ACL_VSTRING_ADDCH(attr->value, ch);
			xml->curr_node->last_ch = ch;

			if ((xml->flag & ACL_XML_FLAG_PART_WORD)) {
				/* 处理半个汉字的情形 */
				if (attr->part_word)
					attr->part_word = 0;
				else if (ch < 0)
					attr->part_word = 1;
			}
		}
		data++;
	}

	ACL_VSTRING_TERMINATE(attr->value);

	if (xml->curr_node->status != ACL_XML_S_AVAL) {
		/* 将该标签ID号映射至哈希表中,以便于快速查询 */
		if (IS_ID(STR(attr->name)) && LEN(attr->value) > 0) {
			const char *ptr = STR(attr->value);

			/* 防止重复ID被插入现象 */
			if (acl_htable_find(xml->id_table, ptr) == NULL) {
				acl_htable_enter(xml->id_table, ptr, attr);

				/* 只有当该属性被加入哈希表后才会赋于结点的 id */
				xml->curr_node->id = attr->value;
			}
		}

		/* 必须将该结点的当前属性对象置空,以便于继续解析时
		 * 可以创建新的属性对象
		 */
		xml->curr_node->curr_attr = NULL;
	}
	return (data);
}
Ejemplo n.º 17
0
Archivo: main.c Proyecto: 10jschen/acl
static void thread_write_fn(void *arg)
{
	char *id = (char*) arg;
	char  key[256], buf[256];
	ACL_VSTRING *value = acl_vstring_alloc(__value_size);
	time_t begin, last, now;
	DICT_POOL_DB *db;
	int   i, n, j;
	KEY *key_array;

	key_array = (KEY*) acl_mycalloc(__max, sizeof(KEY));

	n = __value_size;
	acl_vstring_sprintf(value, "%u:", (unsigned) acl_pthread_self());
	n -= LEN(value);
	for (i = 0; i < n; i++)
		ACL_VSTRING_ADDCH(value, 'v');
	ACL_VSTRING_TERMINATE(value);

	time(&begin);
	last = begin;
	for (j = 0, i = __begin; i < __begin + __max; i++) {
		snprintf(buf, sizeof(buf), "%s:%s:%d", __key_pre, id, i);
#if 0
		MDString(buf, key, sizeof(key));
#else
		acl_uint64 k = acl_hash_crc64(buf, strlen(buf));
		snprintf(key, sizeof(key), "%llu", k);
#endif
		key_array[j++].key = acl_mystrdup(key);
	}

	if (__max <= 100) {
		printf("before sort\n");
		for (i = 0; i < __max; i++) {
			printf("key[%d]: %s\n", i, key_array[i].key);
		}
	}

	if (__sort)
		qsort(key_array, __max, sizeof(KEY), cmp_fn);

	if (__max <= 100) {
		printf("after sort\n");
		for (i = 0; i < __max; i++) {
			printf("key[%d]: %s\n", i, key_array[i].key);
		}
	}

	for (i = 0; i < __max; i++) {
		char *ptr;
		size_t size;

		db = dict_pool_db(__dict_pool, key_array[i].key, strlen(key_array[i].key));
		dict_pool_db_lock(db);
		ptr = dict_pool_db_get(db, key_array[i].key, strlen(key_array[i].key), &size);
		if (ptr != NULL) {
			printf("key: %s exist now, size: %d\n", key_array[i].key, (int) size);
			acl_myfree(ptr);
		}
		dict_pool_db_set(db, key_array[i].key, strlen(key_array[i].key), STR(value), LEN(value));

		ptr = dict_pool_db_get(db, key_array[i].key, strlen(key_array[i].key), &size);
		if (ptr == NULL) {
			printf("key: %s not add into db\n", key_array[i].key);
		} else
			acl_myfree(ptr);
		dict_pool_db_unlock(db);

		if (i > 0 && i % __report_base == 0) {
			time(&now);
			printf("thread %u add one, i=%d, time=%ld, key=%s\r\n",
				(unsigned) acl_pthread_self(), i, now - last, key_array[i].key);
			last = now;
		}
		LOCK;
		__nwrite++;
		UNLOCK;
	}

	for (i = 0; i < __max; i++) {
		acl_myfree(key_array[i].key);
	}
	acl_myfree(key_array);
	acl_vstring_free(value);
	acl_myfree(id);
	printf("thread %u add over, i=%d, time=%ld\r\n",
		(unsigned) acl_pthread_self(), i, time(NULL) - begin);
}
Ejemplo n.º 18
0
ACL_VSTRING *tok822_externalize(ACL_VSTRING *vp, TOK822 *tree, int flags)
{
	ACL_VSTRING *tmp;
	TOK822 *tp;
	ssize_t start = 0;
	TOK822 *addr = 0;
	ssize_t addr_len = 0;

	/*
	 * Guard against a Sendmail buffer overflow (CERT advisory CA-2003-07).
	 * The problem was that Sendmail could store too much non-address text
	 * (comments, phrases, etc.) into a static 256-byte buffer.
	 * 
	 * When the buffer fills up, fixed Sendmail versions remove comments etc.
	 * and reduce the information to just <$g>, which expands to <address>.
	 * No change is made when an address expression (text separated by
	 * commas) contains no address. This fix reportedly also protects
	 * Sendmail systems that are still vulnerable to this problem.
	 * 
	 * Postfix takes the same approach, grudgingly. To avoid unnecessary damage,
	 * Postfix removes comments etc. only when the amount of non-address text
	 * in an address expression (text separated by commas) exceeds 250 bytes.
	 * 
	 * With Sendmail, the address part of an address expression is the
	 * right-most <> instance in that expression. If an address expression
	 * contains no <>, then Postfix guarantees that it contains at most one
	 * non-comment string; that string is the address part of the address
	 * expression, so there is no ambiguity.
	 * 
	 * Finally, we note that stress testing shows that other code in Sendmail
	 * 8.12.8 bluntly truncates ``text <address>'' to 256 bytes even when
	 * this means chopping the <address> somewhere in the middle. This is a
	 * loss of control that we're not entirely comfortable with. However,
	 * unbalanced quotes and dangling backslash do not seem to influence the
	 * way that Sendmail parses headers, so this is not an urgent problem.
	 */
#define MAX_NONADDR_LENGTH 250

#define RESET_NONADDR_LENGTH { \
	start = ACL_VSTRING_LEN(vp); \
	addr = 0; \
	addr_len = 0; \
}

#define ENFORCE_NONADDR_LENGTH do { \
	if (addr && (ssize_t) ACL_VSTRING_LEN(vp) - addr_len > start + MAX_NONADDR_LENGTH) \
		strip_address(vp, start, addr->head); \
} while(0)

	if (flags & TOK822_STR_WIPE)
		ACL_VSTRING_RESET(vp);

	if (flags & TOK822_STR_TRNC)
		RESET_NONADDR_LENGTH;

	for (tp = tree; tp; tp = tp->next) {
		switch (tp->type) {
		case ',':
			if (flags & TOK822_STR_TRNC)
				ENFORCE_NONADDR_LENGTH;
			ACL_VSTRING_ADDCH(vp, tp->type);
			ACL_VSTRING_ADDCH(vp, (flags & TOK822_STR_LINE) ? '\n' : ' ');
			if (flags & TOK822_STR_TRNC)
				RESET_NONADDR_LENGTH;
			continue;

			/*
			 * XXX In order to correctly externalize an address, it is not
			 * sufficient to quote individual atoms. There are higher-level
			 * rules that say when an address localpart needs to be quoted.
			 * We wing it with the quote_822_local() routine, which ignores
			 * the issue of atoms in the domain part that would need quoting.
			 */
		case TOK822_ADDR:
			addr = tp;
			tmp = acl_vstring_alloc(100);
			tok822_internalize(tmp, tp->head, TOK822_STR_TERM);
			addr_len = ACL_VSTRING_LEN(vp);
			quote_822_local_flags(vp, acl_vstring_str(tmp),
				QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_APPEND);
			addr_len = ACL_VSTRING_LEN(vp) - addr_len;
			acl_vstring_free(tmp);
			break;
		case TOK822_ATOM:
		case TOK822_COMMENT:
			acl_vstring_strcat(vp, acl_vstring_str(tp->vstr));
			break;
		case TOK822_QSTRING:
			ACL_VSTRING_ADDCH(vp, '"');
			tok822_copy_quoted(vp, acl_vstring_str(tp->vstr), "\"\\\r\n");
			ACL_VSTRING_ADDCH(vp, '"');
			break;
		case TOK822_DOMLIT:
			ACL_VSTRING_ADDCH(vp, '[');
			tok822_copy_quoted(vp, acl_vstring_str(tp->vstr), "\\\r\n");
			ACL_VSTRING_ADDCH(vp, ']');
			break;
		case TOK822_STARTGRP:
			ACL_VSTRING_ADDCH(vp, ':');
			break;
		case '<':
			if (tp->next && tp->next->type == '>') {
				addr = tp;
				addr_len = 0;
			}
			ACL_VSTRING_ADDCH(vp, '<');
			break;
		default:
			if (tp->type >= TOK822_MINTOK)
				acl_msg_panic("tok822_externalize: unknown operator %d", tp->type);
			ACL_VSTRING_ADDCH(vp, tp->type);
		}
		if (tok822_append_space(tp))
			ACL_VSTRING_ADDCH(vp, ' ');
	}
	if (flags & TOK822_STR_TRNC)
		ENFORCE_NONADDR_LENGTH;

	if (flags & TOK822_STR_TERM)
		ACL_VSTRING_TERMINATE(vp);
	return (vp);
}
Ejemplo n.º 19
0
int     mac_parse(const char *value, MAC_PARSE_FN action, char *context)
{
    const char *myname = "mac_parse";
    ACL_VSTRING *buf = acl_vstring_alloc(1);	/* result buffer */
    const char *vp;			/* value pointer */
    const char *pp;			/* open_paren pointer */
    const char *ep;			/* string end pointer */
    static char open_paren[] = "({";
    static char close_paren[] = ")}";
    int     level;
    int     status = 0;

#define SKIP(start, var, cond) \
        for (var = start; *var && (cond); var++);

    acl_debug(DEBUG_MAC, 2) ("%s: %s", myname, value);

    for (vp = value; *vp;) {
	if (*vp != '$') {			/* ordinary character */
	    ACL_VSTRING_ADDCH(buf, *vp);
	    vp += 1;
	} else if (vp[1] == '$') {		/* $$ becomes $ */
	    ACL_VSTRING_ADDCH(buf, *vp);
	    vp += 2;
	} else {				/* found bare $ */
	    if (ACL_VSTRING_LEN(buf) > 0)
		MAC_PARSE_ACTION(status, MAC_PARSE_LITERAL, buf, context);
	    vp += 1;
	    pp = open_paren;
	    if (*vp == *pp || *vp == *++pp) {	/* ${x} or $(x) */
		level = 1;
		vp += 1;
		for (ep = vp; level > 0; ep++) {
		    if (*ep == 0) {
			acl_msg_warn("truncated macro reference: \"%s\"", value);
			status |= MAC_PARSE_ERROR;
			break;
		    }
		    if (*ep == *pp)
			level++;
		    if (*ep == close_paren[pp - open_paren])
			level--;
		}
		if (status & MAC_PARSE_ERROR)
		    break;
		acl_vstring_strncat(buf, vp, level > 0 ? ep - vp : ep - vp - 1);
		vp = ep;
	    } else {				/* plain $x */
		SKIP(vp, ep, ACL_ISALNUM(*ep) || *ep == '_');
		acl_vstring_strncat(buf, vp, ep - vp);
		vp = ep;
	    }
	    if (ACL_VSTRING_LEN(buf) == 0) {
		status |= MAC_PARSE_ERROR;
		acl_msg_warn("empty macro name: \"%s\"", value);
		break;
	    }
	    MAC_PARSE_ACTION(status, MAC_PARSE_EXPR, buf, context);
	}
    }
    if (ACL_VSTRING_LEN(buf) > 0 && (status & MAC_PARSE_ERROR) == 0)
	MAC_PARSE_ACTION(status, MAC_PARSE_LITERAL, buf, context);

    /*
     * Cleanup.
     */
    acl_vstring_free(buf);

    return (status);
}
Ejemplo n.º 20
0
const char *acl_getenv_list(void)
{
	const char *myname = "acl_getenv_list";
#ifdef ACL_WINDOWS
	static acl_pthread_key_t buf_key = ACL_TLS_OUT_OF_INDEXES;
	ACL_VSTRING *buf;
	LPTSTR lpszVariable;
	LPVOID lpvEnv;
	int   i = 0, ch = 0;

	buf = (ACL_VSTRING*) acl_pthread_tls_get(&buf_key);
	if (buf == NULL) {
		if (buf_key == ACL_TLS_OUT_OF_INDEXES) {
			acl_msg_error("%s(%d): acl_pthread_tls_get error(%s)",
				myname, __LINE__, acl_last_serror());
			return (NULL);
		}
		buf = acl_vstring_alloc(256);
		acl_pthread_tls_set(buf_key, buf, (void (*)(void*)) free_vstring);
	} else
		ACL_VSTRING_RESET(buf);

	lpvEnv = GetEnvironmentStrings();
	for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) {
		if (i++ > 0)
			acl_vstring_strcat(buf, ", ");
		while (*lpszVariable) {
			ACL_VSTRING_ADDCH(buf, *lpszVariable++);
			ch = *lpszVariable;
		}
	}
	FreeEnvironmentStrings(lpvEnv);
	ACL_VSTRING_TERMINATE(buf);
	return (acl_vstring_str(buf));
#else
	static acl_pthread_key_t buf_key = (acl_pthread_key_t) ACL_TLS_OUT_OF_INDEXES;
	ACL_VSTRING *buf;
	extern char **environ;
	char **pptr = environ;
	int   i = 0;

	buf = (ACL_VSTRING*) acl_pthread_tls_get(&buf_key);
	if (buf == NULL) {
		if (buf_key == (acl_pthread_key_t) ACL_TLS_OUT_OF_INDEXES) {
			acl_msg_error("%s(%d): acl_pthread_tls_get error(%s)",
				myname, __LINE__, acl_last_serror());
			return (NULL);
		}
		buf = acl_vstring_alloc(256);
		acl_pthread_tls_set(buf_key, buf, (void (*)(void*)) free_vstring);
	} else
		ACL_VSTRING_RESET(buf);

	while (*pptr) {
		if (i++ > 0)
			acl_vstring_strcat(buf, ", ");
		acl_vstring_strcat(buf, *pptr);
		pptr++;
	}
	return (acl_vstring_str(buf));
#endif
}
Ejemplo n.º 21
0
HTTP_HDR_REQ *http_hdr_req_create(const char *url,
	const char *method, const char *version)
{
	const char *myname = "http_hdr_req_create";
	HTTP_HDR_REQ *hdr_req;
	ACL_VSTRING *req_line = acl_vstring_alloc(256);
	HTTP_HDR_ENTRY *entry;
	const char *ptr;
	static char *__user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.0"
		"; zh-CN; rv:1.9.0.3) Gecko/2008092417 ACL/3.0.6";

	if (url == NULL || *url == 0) {
		acl_msg_error("%s(%d): url invalid", myname, __LINE__);
		return NULL;
	}
	if (method == NULL || *method == 0) {
		acl_msg_error("%s(%d): method invalid", myname, __LINE__);
		return NULL;
	}
	if (version == NULL || *version == 0) {
		acl_msg_error("%s(%d): version invalid", myname, __LINE__);
		return NULL;
	}

	acl_vstring_strcpy(req_line, method);
	acl_vstring_strcat(req_line, " ");

	if (strncasecmp(url, "http://", sizeof("http://") - 1) == 0)
		url += sizeof("http://") - 1;
	else if (strncasecmp(url, "https://", sizeof("https://") - 1) == 0)
		url += sizeof("https://") -1;
	ptr = strchr(url, '/');
	if (ptr)
		acl_vstring_strcat(req_line, ptr);
	else {
		ACL_VSTRING_ADDCH(req_line, '/');
		ACL_VSTRING_TERMINATE(req_line);
	}

	acl_vstring_strcat(req_line, " ");
	acl_vstring_strcat(req_line, version);

	entry = http_hdr_entry_new(acl_vstring_str(req_line));
	acl_vstring_free(req_line);

	if (entry == NULL) {
		acl_msg_error("%s(%d): http_hdr_entry_new return null for (%s)",
			myname, __LINE__, acl_vstring_str(req_line));
		return NULL;
	}

	hdr_req = http_hdr_req_new();
	http_hdr_append_entry(&hdr_req->hdr, entry);
	hdr_req->flag |= (HTTP_HDR_REQ_FLAG_PARSE_PARAMS | HTTP_HDR_REQ_FLAG_PARSE_COOKIE);
	if (http_hdr_req_line_parse(hdr_req) < 0) {
		http_hdr_req_free(hdr_req);
		return NULL;
	}

	hdr_req->host[0] = 0;
	__get_host_from_url(hdr_req->host, sizeof(hdr_req->host), url);
	if (hdr_req->host[0] != 0)
		http_hdr_put_str(&hdr_req->hdr, "Host", hdr_req->host);
	http_hdr_put_str(&hdr_req->hdr, "Connection", "Close");
	http_hdr_put_str(&hdr_req->hdr, "User-Agent", __user_agent);

	return hdr_req;
}
Ejemplo n.º 22
0
ACL_VSTRING *unescape(ACL_VSTRING *result, const char *data)
{
	int     ch;
	int     oval;
	int     i;

#define UCHAR(cp)	((const unsigned char *) (cp))
#define ISOCTAL(ch)	(ACL_ISDIGIT(ch) && (ch) != '8' && (ch) != '9')

	ACL_VSTRING_RESET(result);

	while ((ch = *UCHAR(data++)) != 0) {
		if (ch == '\\') {
			if ((ch = *UCHAR(data++)) == 0)
				break;
			switch (ch) {
			case 'a':				/* \a -> audible bell */
				ch = '\a';
				break;
			case 'b':				/* \b -> backspace */
				ch = '\b';
				break;
			case 'f':				/* \f -> formfeed */
				ch = '\f';
				break;
			case 'n':				/* \n -> newline */
				ch = '\n';
				break;
			case 'r':				/* \r -> carriagereturn */
				ch = '\r';
				break;
			case 't':				/* \t -> horizontal tab */
				ch = '\t';
				break;
			case 'v':				/* \v -> vertical tab */
				ch = '\v';
				break;
			case '0':				/* \nnn -> ASCII value */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
				for (oval = ch - '0', i = 0;
					i < 2 && (ch = *UCHAR(data)) != 0 && ISOCTAL(ch);
					i++, data++) {
					oval = (oval << 3) | (ch - '0');
				}
				ch = oval;
				break;
			default:				/* \any -> any */
				break;
			}
		}
		ACL_VSTRING_ADDCH(result, ch);
	}
	ACL_VSTRING_TERMINATE(result);
	return (result);
}