Beispiel #1
0
int     main(int unused_argc, char **argv)
{
    ACL_HTABLE *table = acl_htable_create(1);

    acl_msg_verbose = 1;
    acl_htable_enter(table, "foo-name", mystrdup("foo-value"));
    acl_htable_enter(table, "bar-name", mystrdup("bar-value"));
    attr_print64(ACL_VSTREAM_OUT, ATTR_FLAG_NONE,
		 ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
		 ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
		 ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
		 ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
		 ATTR_TYPE_HASH, table,
		 ATTR_TYPE_END);
    attr_print64(ACL_VSTREAM_OUT, ATTR_FLAG_NONE,
		 ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
		 ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
		 ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
		 ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
		 ATTR_TYPE_END);
    if (acl_vstream_fflush(ACL_VSTREAM_OUT) == ACL_VSTREAM_EOF)
	acl_msg_fatal("%s: write error", __FUNCTION__);

    acl_htable_free(table, myfree);
    return (0);
}
Beispiel #2
0
static void clone_table_entry(ACL_HTABLE_INFO *info, void *arg)
{
	const char *myname = "clone_table_entry";
	ACL_HTABLE *table = (ACL_HTABLE*) arg;
	char *value;

	value = acl_mystrdup(info->value);

	if (acl_htable_enter(table, info->key.key, value) == NULL)
		acl_msg_fatal("%s, %s(%d): acl_htable_enter error=%s",
			__FILE__, myname, __LINE__, acl_last_serror());
}
Beispiel #3
0
FILE_CACHE *file_cache_new(const char *file_path, time_t last_modified)
{
    FILE_CACHE *cache;

    cache = (FILE_CACHE*) acl_mymalloc(sizeof(FILE_CACHE));
    cache->size = 0;
    http_mkrfc1123(cache->tm_mtime, sizeof(cache->tm_mtime), last_modified);
    ACL_SAFE_STRNCPY(cache->path, file_path, sizeof(cache->path));
    cache->fifo = acl_fifo_new();
    (void) acl_htable_enter(__cache_table, file_path, (char*) cache);
    return (cache);
}
Beispiel #4
0
SERVICE_CTX *service_ctx_new(SERVICE *service, ACL_ASTREAM *stream,
	char type, unsigned short id)
{
	const char *myname = "service_ctx_new";
	SERVICE_CTX *ctx = (SERVICE_CTX*) acl_mycalloc(1, sizeof(SERVICE_CTX));

	ctx->service = service;
	ctx->stream = stream;
	ctx->type = type;
	ctx->id = id;

	create_key(ctx->key, sizeof(ctx->key), type, id);

	if (acl_htable_enter(service->table, ctx->key, ctx) == NULL)
		acl_msg_fatal("%s(%d): enter to table error, key(%s)",
			myname, __LINE__, ctx->key);
	return (ctx);
}
Beispiel #5
0
int main(int argc, char *argv[])
{
	ACL_HTABLE *htable;
	char  key[128], *value;
	int   i, n = 50, ch, flag = 0;

	while ((ch = getopt(argc, argv, "hn:m")) > 0) {
		switch (ch) {
		case 'h':
			usage(argv[0]);
			return (0);
		case 'n':
			n = atoi(optarg);
			break;
		case 'm':
			flag |= ACL_HTABLE_FLAG_MSLOOK;
			break;
		default:
			break;
		}
	}

	htable = acl_htable_create(1, flag);

	for (i = 0; i < n; i++) {
		value = (char*) acl_mymalloc(256);
		snprintf(value, 256, "value:%d", i);
		snprintf(key, sizeof(key), "key:%d", i);
		acl_htable_enter(htable, key, value);
	}
	acl_htable_stat(htable);

	printf("------------------------------------------------------------\n");
	for (i = n - 1; i >= 0; i--) {
		snprintf(key, sizeof(key), "key:%d", i);
		(void) acl_htable_find(htable, key);
	}
	acl_htable_stat(htable);

	acl_htable_free(htable, free_fn);
	return (0);
}
Beispiel #6
0
ACL_MDT *acl_mdb_tbl_create(ACL_MDB *mdb, const char *tbl_name,
	unsigned int tbl_flag, size_t init_capacity,
	const char *key_labels[], unsigned int flags[])
{
	const char *myname = "acl_mdb_tbl_create";
	ACL_MDT *mdt;

	if (mdb == NULL || tbl_name == NULL || *tbl_name == 0) {
		acl_msg_error("%s(%d): input invalid", myname, __LINE__);
		return (NULL);
	}

	if (init_capacity < 128)
		init_capacity = 128;

	mdt = acl_mdt_create(mdb->type, tbl_name, tbl_flag,
			init_capacity, key_labels, flags);

	if (acl_htable_enter(mdb->tbls, tbl_name, (char *) mdt) == NULL)
		acl_msg_fatal("%s(%d): acl_htable_enter error, tbl_name = %s",
			myname, __LINE__, tbl_name);

	return (mdt);
}
Beispiel #7
0
static void __add_cookie_item(ACL_HTABLE *table, const char *data)
{
/* data format: name=value */
	const char *myname = "__add_cookie_item";
	ACL_ARGV *argv = NULL;
	ACL_VSTRING *str = NULL;
	const char *name;
	char *value;
	char *ptr;
	int   i;

#undef	RETURN
#define	RETURN do {  \
	if (argv)  \
		acl_argv_free(argv);  \
	return;  \
} while(0);

#undef	TRUNC_BLANK
#define	TRUNC_BLANK(_x_) do {  \
	char *_ptr_;  \
	while(*_x_ == ' ' || *_x_ == '\t')  \
		_x_++;  \
	if (*_x_ == 0)  \
		RETURN;  \
	_ptr_ = _x_;  \
	while (*_ptr_) {  \
		if (*_ptr_ == ' ' || *_ptr_ == '\t') {  \
			*_ptr_ = 0;  \
			break;  \
		}  \
		_ptr_++;  \
	}  \
} while (0);

#undef	TRUNC_BLANK_NORETURN
#define	TRUNC_BLANK_NORETURN(_x_) do {  \
	char *_ptr_;  \
	while(*_x_ == ' ' || *_x_ == '\t')  \
		_x_++;  \
	_ptr_ = _x_;  \
	while (*_ptr_) {  \
		if (*_ptr_ == ' ' || *_ptr_ == '\t') {  \
			*_ptr_ = 0;  \
			break;  \
		}  \
		_ptr_++;  \
	}  \
} while (0);

	argv = acl_argv_split(data, "=");
	if (argv->argc < 2)   /* data: "name" or "name="*/
		RETURN;

	ptr = acl_argv_index(argv, 0);
	TRUNC_BLANK(ptr);
	name = ptr;

	/* 有些站点的COOKIE比较弱,如和讯的reg.hexun.com,COOKIE名会有重复
	 * 的情况,所以必须判断一下,不必重复存储相同名字的COOKIE值,即如果
	 * 出现重复COOKIE名,则只存储第一个,这样就避免了采用哈希方式存储的
	 * 漏内存的现象发生。--- zsx, 2008.1.8
	 */
	if (acl_htable_find(table, name) != NULL) {
		RETURN;
	}

	str = acl_vstring_alloc(256);

	for (i = 1; i < argv->argc; i++) {
		ptr = acl_argv_index(argv, i);
		if (ptr == NULL)
			break;
		TRUNC_BLANK_NORETURN(ptr);
		if (*ptr == 0)
			continue;
		if (i == 1)
			acl_vstring_sprintf_append(str, "%s", ptr);
		else
			acl_vstring_sprintf_append(str, "=%s", ptr);
	}

	/* 将真实的存储数据的区域内存引出, 同时将外包结构内存释放,
	 * POSTFIX真是个好东西:) ---zsx
	 */
	value = acl_vstring_export(str);

	if (acl_htable_enter(table, name, value) == NULL)
		acl_msg_fatal("%s, %s(%d): acl_htable_enter error=%s",
			__FILE__, myname, __LINE__, acl_last_serror());

	RETURN;
}
Beispiel #8
0
static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data)
{
    int   ch;
    ACL_XML2_ATTR *attr = xml->curr_node->curr_attr;

    if (attr->value == xml->addr && !attr->quote) {
        SKIP_SPACE(data);
        if (IS_QUOTE(*data))
            attr->quote = *data++;
    }

    if (*data == 0)
        return data;

    if (attr->value == xml->addr)
        attr->value = xml->ptr;

    while ((ch = *data) != 0) {
        if (attr->quote) {
            if (ch == attr->quote) {
                if (xml->len < MIN_LEN)
                    return data;
                data++;
                xml->len--;
                attr->value_size = xml->ptr - attr->value;
                *xml->ptr++ = 0;
                xml->curr_node->status = ACL_XML2_S_ATTR;
                xml->curr_node->last_ch = ch;
                break;
            }

            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
            xml->curr_node->last_ch = ch;
        } else if (ch == '>') {
            if (xml->len < MIN_LEN)
                return data;
            data++;
            xml->len--;
            attr->value_size = xml->ptr - attr->value;
            *xml->ptr++ = 0;

            xml_parse_check_self_closed(xml);

            if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL)
                    && xml->curr_node->last_ch == '/')
            {
                if (attr->value_size >= 2)
                    attr->value[attr->value_size - 2] = 0;
                xml->curr_node->status = ACL_XML2_S_RGT;
            } else
                xml->curr_node->status = ACL_XML2_S_LGT;
            break;
        } else if (IS_SPACE(ch)) {
            if (xml->len < MIN_LEN)
                return data;
            data++;
            xml->len--;
            attr->value_size = xml->ptr - attr->value;
            *xml->ptr++ = 0;
            xml->curr_node->status = ACL_XML2_S_ATTR;
            xml->curr_node->last_ch = ch;
            break;
        } else {
            if (xml->len < MIN_LEN)
                return data;
            xml->len--;
            *xml->ptr++ = ch;
            xml->curr_node->last_ch = ch;
        }

        data++;
    }

    /* 说明属性值还未解析完,需要继续解析 */
    if (xml->curr_node->status == ACL_XML2_S_AVAL)
        return data;

    /* 当状态发生改变时,则说明属性值已经完毕 */

    if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1
            && xml->len > 0)
    {
        const char *val = attr->value;

        attr->value = xml->ptr;
        (void) acl_xml_decode2(val, &xml->ptr, &xml->len);
        attr->value_size = xml->ptr - attr->value - 1;
    }

    /* 将该标签ID号映射至哈希表中,以便于快速查询 */
    if (IS_ID(attr->name) && *attr->value != 0) {
        const char *ptr = 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;
}
Beispiel #9
0
static char *xml_parse_attr_val(ACL_XML3 *xml, char *data)
{
	int   ch;
	ACL_XML3_ATTR *attr = xml->curr_node->curr_attr;

	if (attr->value == xml->addr && !attr->quote) {
		SKIP_SPACE(data);
		if (IS_QUOTE(*data))
			attr->quote = *data++;
	}

	if (*data == 0)
		return data;

	if (attr->value == xml->addr)
		attr->value = data;

	while ((ch = *data) != 0) {
		if (attr->quote) {
			if (ch == attr->quote) {
				attr->value_size = data - attr->value;
				xml->curr_node->status = ACL_XML3_S_ATTR;
				xml->curr_node->last_ch = ch;
				*data++ = 0;
				break;
			}

			xml->curr_node->last_ch = ch;
		} else if (ch == '>') {
			if (attr->value_size == 0)
				attr->value_size = data - attr->value;
			*data++ = 0;

			xml_parse_check_self_closed(xml);

			if ((xml->curr_node->flag & ACL_XML3_F_SELF_CL)
				&& xml->curr_node->last_ch == '/')
			{
				if (attr->value_size >= 2)
					attr->value[attr->value_size - 2] = 0;
				xml->curr_node->status = ACL_XML3_S_RGT;
			} else
				xml->curr_node->status = ACL_XML3_S_LGT;
			break;
		} else if (IS_SPACE(ch)) {
			attr->value_size = data - attr->value;
			xml->curr_node->status = ACL_XML3_S_ATTR;
			xml->curr_node->last_ch = ch;
			*data++ = 0;
			break;
		} else
			xml->curr_node->last_ch = ch;

		data++;
	}

	/* 当状态发生改变时,则说明属性值已经完毕 */
	if (xml->curr_node->status != ACL_XML3_S_AVAL) {
		/* 将该标签ID号映射至哈希表中,以便于快速查询 */
		if (IS_ID(attr->name) && *attr->value != 0) {
			char *ptr = 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;
}
Beispiel #10
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);
}
Beispiel #11
0
/* 查询DNS信息,采用外挂模块的方式 */
static void thrpool_nslookup(SERVICE *service, CLIENT_ENTRY *entry,
	const char *domain, int port)
{
	const char *myname = "thrpool_nslookup";
	DNS_CTX dns_ctx;
	DNS_RING *list;
	char *ptr;

	entry->tm.stamp = time(NULL);

	memset(&dns_ctx, 0, sizeof(dns_ctx));
	dns_ctx.begin = entry->tm.stamp;
	STRNCPY(dns_ctx.domain_key, domain, sizeof(dns_ctx.domain_key));
	ptr = strchr(dns_ctx.domain_key, ':');
	/* 仅留下域名部分 */
	if (ptr)
		*ptr = 0;

	entry->server_port = port;
	if (entry->server_port <= 0)
		entry->server_port = 80;
	
	/* 将域名字符串都转换成小写,以便于进行哈希查询 */
	acl_lowercase(dns_ctx.domain_key);

	dns_ctx.context = service;
	dns_ctx.callback = thrpool_nslookup_complete;

	STRNCPY(entry->domain_key, dns_ctx.domain_key, sizeof(entry->domain_key));

	/* 先查询DNS查询表中是否已经包含本次需要被查询的域名 */
	list = (DNS_RING *) acl_htable_find(service->dns_table, dns_ctx.domain_key);
	if (list) {
		/* 将本次对同一域名的查询添加进同一个查询链中 */
		acl_ring_prepend(&list->ring, &entry->dns_entry);
		/* 将查询链对象的引用计数加1 */
		list->nrefer++;
		/* 如果该查询链已经存在,说明有查询任务等待返回,其返回后会一同将
		 * 本次任务进行触发,如果此处触发新任务,则会造成内存访问冲突,因为
		 * 查询DNS的过程是由一组线程池进行查询的。
		 * (void) dns_server_lookup(proxy_entry->aio_proxy->dns_server, &dns_ctx);
		 */
		return;
	}

	/* 创建一个新的查询链对象,并将本次查询任务加入该查询链中及将该查询链加入查询表中 */

	list = (DNS_RING *) acl_mycalloc(1, sizeof(DNS_RING));
	acl_ring_init(&list->ring);
	STRNCPY(list->domain_key, dns_ctx.domain_key, sizeof(list->domain_key));

	/* 将本次查询任务加入新的查询链中且将查询链的引用计数加1 */
	acl_ring_prepend(&list->ring, &entry->dns_entry);
	list->nrefer++;

	/* 将新的查询链加入查询表中 */
	if (acl_htable_enter(service->dns_table, list->domain_key, (char *) list) == NULL)
		acl_msg_fatal("%s: add domain(%s) to table error", myname, list->domain_key);

	/* 开始启动DNS查询过程 */
	(void) dns_server_lookup(service->dns_server, &dns_ctx);
}