Example #1
0
int parse_avp_spec( str *name, int *type, int_str *avp_name)
{
	char *p;

	if (name==0 || name->s==0 || name->len==0)
		return -1;

	p = (char*)memchr((void*)name->s, AVP_NAME_DELIM, name->len);
	if (p==NULL) {
		/* it's an avp alias */
		return lookup_avp_galias( name, type, avp_name);
	} else {
		return parse_avp_name( name, type, avp_name);
	}
}
Example #2
0
int xl_parse_format(char *s, xl_elog_p *el)
{
	char *p, c;
	int n = 0;
	xl_elog_p e, e0;
	struct hdr_field  hdr;
	str name;
	int avp_flags, avp_index;
	int_str avp_name;
	select_t *sel;
	
	if(s==NULL || el==NULL)
		return -1;

	DBG("XLOG: xl_parse_format: parsing [%s]\n", s);

	p = s;
	*el = NULL;
	e = e0 = NULL;

	while(*p)
	{
		e0 = e;
		e = pkg_malloc(sizeof(xl_elog_t));
		if(!e)
			goto error;
		memset(e, 0, sizeof(xl_elog_t));
		n++;
		if(*el == NULL)
			*el = e;
		if(e0)
			e0->next = e;

		e->text.s = p;
		while(*p && *p!='%')
			p++;
		e->text.len = p - e->text.s;
		if(*p == '\0')
			break;

		p++;
		switch(*p)
		{
			case 'b':
				p++;
				switch(*p)
				{
					case 'r':
						e->itf = xl_get_branch;
					break;
					case 'R':
						e->itf = xl_get_branches;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'c':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_callid;
					break;
					case 's':
						e->itf = xl_get_cseq;
					break;
					case 't':
						e->itf = xl_get_contact;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'C':
				p++;
				e->hparam.s = p;

				/* foreground */
				switch(*p)
                {
					case 'x':
					case 's': case 'r': case 'g':
					case 'y': case 'b': case 'p':
					case 'c': case 'w': case 'S':
					case 'R': case 'G': case 'Y':
					case 'B': case 'P': case 'C':
					case 'W':
					break;
					default:
						e->itf = xl_get_empty;
						goto error;
				}
				p++;

				/* background */
				switch(*p)
				{
					case 'x':
					case 's': case 'r': case 'g':
					case 'y': case 'b': case 'p':
					case 'c': case 'w':
					break;
					default:
						e->itf = xl_get_empty;
						goto error;
				}

				/* end */
				e->hparam.len = 2;
				e->itf = xl_get_color;
			break;
			case 'd':
				p++;
				switch(*p)
				{
					case 's':
						e->itf = xl_get_dset;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'f':
				p++;
				switch(*p)
				{
					case 'u':
						e->itf = xl_get_from;
					break;
					case 't':
						e->itf = xl_get_from_tag;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'H':
				p++;
				e->itf = xl_get_host;
				switch(*p)
				{
					case 'n':
						e->hindex = XL_HOST_NAME;
					break;
					case 'd':
						e->hindex = XL_HOST_DOMAIN;
					break;
					case 'f':
						e->hindex = XL_HOST_FULL;
					break;
					case 'i':
						e->hindex = XL_HOST_IPADDR;
					break;
					default:
						e->hindex = XL_HOST_NULL;
						break;
				}
				break;
			case 'm':
				p++;
				switch(*p)
				{
					case 'b':
						e->itf = xl_get_msg_buf;
					break;
					case 'f':
						e->itf = xl_get_flags;
					break;
					case 'i':
						e->itf = xl_get_msgid;
						e->hindex = 10;
					break;
					case 'l':
						e->itf = xl_get_msg_len;
					break;
					case 'x':
						e->itf = xl_get_msgid;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
				break;
			case 'n':
				p++;
				switch(*p)
				{
					case 'h':
						e->itf = xl_get_nexthop;
					break;
					default:
						e->itf = xl_get_null;
				}
				break;
			case 'p':
				p++;
				switch(*p)
				{
					case 'p':
						e->itf = xl_get_pid;
						e->hindex = 10;
					break;
					case 'x':
						e->itf = xl_get_pid;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'r':
				p++;
				switch(*p)
				{
					case 'm':
						e->itf = xl_get_method;
					break;
					case 'u':
						e->itf = xl_get_ruri;
					break;
					case 's':
						e->itf = xl_get_status;
					break;
					case 'r':
						e->itf = xl_get_reason;
					break;
					case 't':
						e->itf = xl_get_refer_to;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'R':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_rcvip;
					break;
					case 'p':
						e->itf = xl_get_rcvport;
					break;
					default:
					e->itf = xl_get_null;
				}
			break;
			case 's':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_srcip;
					break;
					case 'p':
						e->itf = xl_get_srcport;
					break;
					default:
					e->itf = xl_get_null;
				}
			break;
			case 't':
				p++;
				switch(*p)
				{
					case 'u':
						e->itf = xl_get_to;
					break;
					case 't':
						e->itf = xl_get_to_tag;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'T':
				p++;
				switch(*p)
				{
					case 's':
						e->itf = xl_get_times;
						e->hindex = 10;
					break;
					case 'f':
						e->itf = xl_get_timef;
					break;
					case 'x':
						e->itf = xl_get_times;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'u':
				p++;
				switch(*p)
				{
					case 'a':
						e->itf = xl_get_useragent;
					break;
					case 'q':
						e->itf = xl_get_unique;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case '{':
				p++;
				/* we expect a letter */
				if((*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z'))
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] pos [%d]\n", s, (int)(p-s));
					goto error;
				}
				e->hparam.s = p;
				while(*p && *p!='}' && *p!='[')
					p++;
				if(*p == '\0')
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] expecting '}' after position [%d]\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				e->hparam.len = p - e->hparam.s;
				/* check if we have index */
				if(*p == '[')
				{
					p++;
					if(*p=='-')
					{
						p++;
						if(*p!='1')
						{
							LOG(L_ERR, "xlog: xl_parse_format: error"
								" parsing format [%s] -- only -1 is accepted"
								" as a negative index\n", s);
								goto error;
						}
						e->hindex = XLOG_PRINT_LAST;
						p++;
					} else if (*p=='*') {
						e->hindex = XLOG_PRINT_ALL;
						p++;
					} else {
						while(*p>='0' && *p<='9')
						{
							e->hindex = e->hindex * 10 + *p - '0';
							p++;
						}
					}
					if(*p != ']')
					{
						LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
							" [%s] expecting ']' after position [%d]\n", s,
							(int)(e->hparam.s - s + e->hparam.len));
						goto error;
					}
					p++;
				}
				if(*p != '}')
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] expecting '}' after position [%d]!\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				DBG("xlog: xl_parse_format: header name [%.*s] index [%d]\n",
						e->hparam.len, e->hparam.s, e->hindex);

				/* optimize for known headers -- fake header name */
				c = e->hparam.s[e->hparam.len];
				e->hparam.s[e->hparam.len] = ':';
				e->hparam.len++;
				/* ugly hack for compact header names -- !!fake length!!
				 * -- parse_hname2 expects name buffer length >= 4
				 */
				if (parse_hname2(e->hparam.s,
						e->hparam.s + ((e->hparam.len<4)?4:e->hparam.len),
						&hdr)==0)
				{
					LOG(L_ERR,"xlog: xl_parse_format: strange error\n");
					goto error;
				}
				e->hparam.len--;
				e->hparam.s[e->hparam.len] = c;
				if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
				{
					LOG(L_INFO,"INFO:xlog: xl_parse_format: using "
						"hdr type (%d) instead of <%.*s>\n",
						hdr.type, e->hparam.len, e->hparam.s);
					e->hparam.len = hdr.type;
					e->hparam.s = NULL;
				}
				e->itf = xl_get_header;
			break;
			case '<':
				p++;
				/* we expect a letter */
				if((*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z'))
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] pos [%d]\n", s, (int)(p-s));
					goto error;
				}
				e->hparam.s = p;
				while(*p && *p!='>' && *p!='[')
					p++;
				if(*p == '\0')
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] expecting '>' after position [%d]\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				e->hparam.len = p - e->hparam.s;
				/* check if we have index */
				if(*p == '[')
				{
					p++;
					if(*p=='-')
					{
						p++;
						if(*p!='1')
						{
							LOG(L_ERR, "xlog: xl_parse_format: error"
								" parsing format [%s] -- only -1 is accepted"
								" as a negative index\n", s);
								goto error;
						}
						e->hindex = -1;
						p++;
					}
					else
					{
						while(*p>='0' && *p<='9')
						{
							e->hindex = e->hindex * 10 + *p - '0';
							p++;
						}
					}
					if(*p != ']')
					{
						LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
							" [%s] expecting ']' after position [%d]\n", s,
							(int)(e->hparam.s - s + e->hparam.len));
						goto error;
					}
					p++;
				}
				if(*p != '>')
				{
					LOG(L_ERR, "xlog: xl_parse_format: error parsing format"
						" [%s] expecting '>' after position [%d]!\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				DBG("xlog: xl_parse_format: AVP [%.*s] index [%d]\n",
						e->hparam.len, e->hparam.s, e->hindex);

				e->itf = xl_get_avp;
			break;
			case '$':
				p++;
				name.s=p;
				while ( (*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || (*p=='_') || (*p=='+') || (*p=='-') || (*p=='[') || (*p==']') || (*p=='.') ) p++;
				name.len=p-name.s;
				p--;
				if (parse_avp_name(&name, &avp_flags, &avp_name, &avp_index) < 0) {
					ERR("error while parsing AVP name\n");
					goto error;
				}
				e->itf = xl_get_avp;
				e->hflags=avp_flags;
				e->hparam.s=name.s;
				e->hparam.len=name.len;
				e->hindex=avp_index;
				DBG("flags %x  name %.*s  index %d\n", avp_flags, avp_name.s.len, avp_name.s.s, avp_index);
				break;
			case '@':
					/* fill select structure and call resolve_select */
				DBG("xlog: xl_parse_format: @\n");
				n=parse_select(&p, &sel);
				if (n<0) {
					ERR("xlog: xl_parse_format: parse_select returned error\n");
					goto error;
				}
				e->itf = xl_get_select;
				e->hparam.s = (char*)sel;
				p--;
				break;
			case '%':
				e->itf = xl_get_percent;
				break;
			case ' ':	/* enables spaceless terminating of avp, e.g. "blah%$avp% text goes on" */
			case '|':
				e->itf = xl_get_empty;
				break;
			default:
				e->itf = xl_get_null;
		}

		if(*p == '\0')
			break;
		p++;
	}
	DBG("XLOG: xl_parse_format: format parsed OK: [%d] items\n", n);

	return 0;

error:
	xl_elog_free_all(*el);
	*el = NULL;
	return -1;
}
Example #3
0
/* Parse an xl-formatted string pointed by s.
 * el points to the resulted linked list that is allocated
 * in shared memory when shm==1 otherwise in pkg memory.
 * If parse_cb is not NULL then regular expression back references
 * are passed to the parse_cb function that is supposed to farther parse
 * the back reference and fill in the xl_elog_t structure.
 *
 * Return value:
 *   0: success
 *  -1: error
 */
static int _xl_parse_format(char *s, xl_elog_p *el, int shm, xl_parse_cb parse_cb)
{
	char *p, c;
	int n = 0;
	xl_elog_p e, e0;
	struct hdr_field  hdr;
	str name;
	int avp_flags, avp_index;
	int_str avp_name;
	select_t *sel;
	int *range;
	
	if(s==NULL || el==NULL)
		return -1;

	DBG("XLOG: xl_parse_format: parsing [%s]\n", s);

	p = s;
	*el = NULL;
	e = e0 = NULL;
	range = NULL;

	while(*p)
	{
		e0 = e;
		if (shm)
			e = shm_malloc(sizeof(xl_elog_t));
		else
			e = pkg_malloc(sizeof(xl_elog_t));
		if(!e)
			goto error;
		memset(e, 0, sizeof(xl_elog_t));
		n++;
		if(*el == NULL)
			*el = e;
		if(e0)
			e0->next = e;

		e->text.s = p;
		while(*p && *p!='%' && *p!='\\' && !range)
			p++;

		e->text.len = p - e->text.s;
		if(*p == '\0')
			break;

		if ((*p == '\\') && !range) {
			p++;
			switch(*p)
			{
				case '\\':
					e->itf = xl_get_special;
					e->hindex = '\\';
					break;
				case 'r':
					e->itf = xl_get_special;
					e->hindex = '\r';
					break;
				case 'n':
					e->itf = xl_get_special;
					e->hindex = '\n';
					break;
				case 't':
					e->itf = xl_get_special;
					e->hindex = '\t';
					break;
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					/* Regular expression back reference found */
					if (!parse_cb) {
						/* There is no callback function, hence the
						 * result will be written as it is. */
						e->itf = xl_get_special;
						e->hindex = *p;
						break;
					}
					name.s = p;
					/* eat all the numeric characters */
					while ((*(p+1) >= '0') && (*(p+1) <= '9'))
						p++;
					name.len = p - name.s + 1;
					if (parse_cb(&name, shm, e)) {
						ERR("xprint: xl_parse_format: failed to parse '%.*s'\n",
							name.len, name.s);
						goto error;
					}
					break;
				default:
					/* not a special character, it will be just
					written to the result as it is */
					e->itf = xl_get_special;
					e->hindex = *p;
			}
			goto cont;
		}

		if (range)
			range = NULL;
		else
			p++;
		switch(*p)
		{
			case 'b':
				p++;
				switch(*p)
				{
					case 'r':
						e->itf = xl_get_branch;
					break;
					case 'R':
						e->itf = xl_get_branches;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'c':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_callid;
					break;
					case 's':
						e->itf = xl_get_cseq;
					break;
					case 't':
						e->itf = xl_get_contact;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'C':
				p++;
				e->hparam.s = p;

				/* foreground */
				switch(*p)
                {
					case 'x':
					case 's': case 'r': case 'g':
					case 'y': case 'b': case 'p':
					case 'c': case 'w': case 'S':
					case 'R': case 'G': case 'Y':
					case 'B': case 'P': case 'C':
					case 'W':
					break;
					default:
						e->itf = xl_get_empty;
						goto error;
				}
				p++;

				/* background */
				switch(*p)
				{
					case 'x':
					case 's': case 'r': case 'g':
					case 'y': case 'b': case 'p':
					case 'c': case 'w':
					break;
					default:
						e->itf = xl_get_empty;
						goto error;
				}

				/* end */
				e->hparam.len = 2;
				e->itf = xl_get_color;
			break;
			case 'd':
				p++;
				switch(*p)
				{
					case 's':
						e->itf = xl_get_dset;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'f':
				p++;
				switch(*p)
				{
					case 'u':
						e->itf = xl_get_from;
					break;
					case 't':
						e->itf = xl_get_from_tag;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'H':
				p++;
				e->itf = xl_get_host;
				switch(*p)
				{
					case 'n':
						e->hindex = XL_HOST_NAME;
					break;
					case 'd':
						e->hindex = XL_HOST_DOMAIN;
					break;
					case 'f':
						e->hindex = XL_HOST_FULL;
					break;
					case 'i':
						e->hindex = XL_HOST_IPADDR;
					break;
					default:
						e->hindex = XL_HOST_NULL;
						break;
				}
				break;
			case 'm':
				p++;
				switch(*p)
				{
					case 'b':
						e->itf = xl_get_msg_buf;
					break;
					case 'f':
						e->itf = xl_get_flags;
					break;
					case 'i':
						e->itf = xl_get_msgid;
						e->hindex = 10;
					break;
					case 'l':
						e->itf = xl_get_msg_len;
					break;
					case 'x':
						e->itf = xl_get_msgid;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
				break;
			case 'n':
				p++;
				switch(*p)
				{
					case 'h':
						e->itf = xl_get_nexthop;
					break;
					default:
						e->itf = xl_get_null;
				}
				break;
			case 'p':
				p++;
				switch(*p)
				{
					case 'p':
						e->itf = xl_get_pid;
						e->hindex = 10;
					break;
					case 'x':
						e->itf = xl_get_pid;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'r':
				p++;
				switch(*p)
				{
					case 'm':
						e->itf = xl_get_method;
					break;
					case 'u':
						e->itf = xl_get_ruri;
					break;
					case 's':
						e->itf = xl_get_status;
					break;
					case 'r':
						e->itf = xl_get_reason;
					break;
					case 't':
						e->itf = xl_get_refer_to;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'R':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_rcvip;
					break;
					case 'p':
						e->itf = xl_get_rcvport;
					break;
					default:
					e->itf = xl_get_null;
				}
			break;
			case 's':
				p++;
				switch(*p)
				{
					case 'i':
						e->itf = xl_get_srcip;
					break;
					case 'p':
						e->itf = xl_get_srcport;
					break;
					default:
					e->itf = xl_get_null;
				}
			break;
			case 't':
				p++;
				switch(*p)
				{
					case 'u':
						e->itf = xl_get_to;
					break;
					case 't':
						e->itf = xl_get_to_tag;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'T':
				p++;
				switch(*p)
				{
					case 's':
						e->itf = xl_get_times;
						e->hindex = 10;
					break;
					case 'f':
						e->itf = xl_get_timef;
					break;
					case 'x':
						e->itf = xl_get_times;
						e->hindex = 16;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case 'u':
				p++;
				switch(*p)
				{
					case 'a':
						e->itf = xl_get_useragent;
					break;
					case 'q':
						e->itf = xl_get_unique;
					break;
					default:
						e->itf = xl_get_null;
				}
			break;
			case '{':
				p++;
				/* we expect a letter */
				if((*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z'))
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] pos [%d]\n", s, (int)(p-s));
					goto error;
				}
				e->hparam.s = p;
				while(*p && *p!='}' && *p!='[')
					p++;
				if(*p == '\0')
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] expecting '}' after position [%d]\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				e->hparam.len = p - e->hparam.s;
				/* check if we have index */
				if(*p == '[')
				{
					p++;
					if(*p=='-')
					{
						p++;
						if(*p!='1')
						{
							LOG(L_ERR, "xprint: xl_parse_format: error"
								" parsing format [%s] -- only -1 is accepted"
								" as a negative index\n", s);
								goto error;
						}
						e->hindex = XLOG_PRINT_LAST;
						p++;
					} else if (*p=='*') {
						e->hindex = XLOG_PRINT_ALL;
						p++;
					} else {
						while(*p>='0' && *p<='9')
						{
							e->hindex = e->hindex * 10 + *p - '0';
							p++;
						}
					}
					if(*p != ']')
					{
						LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
							" [%s] expecting ']' after position [%d]\n", s,
							(int)(e->hparam.s - s + e->hparam.len));
						goto error;
					}
					p++;
				}
				if(*p != '}')
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] expecting '}' after position [%d]!\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				DBG("xprint: xl_parse_format: header name [%.*s] index [%d]\n",
						e->hparam.len, e->hparam.s, e->hindex);

				/* optimize for known headers -- fake header name */
				c = e->hparam.s[e->hparam.len];
				e->hparam.s[e->hparam.len] = ':';
				e->hparam.len++;
				/* ugly hack for compact header names -- !!fake length!!
				 * -- parse_hname2 expects name buffer length >= 4
				 */
				if (parse_hname2(e->hparam.s,
						e->hparam.s + ((e->hparam.len<4)?4:e->hparam.len),
						&hdr)==0)
				{
					LOG(L_ERR,"xprint: xl_parse_format: strange error\n");
					goto error;
				}
				e->hparam.len--;
				e->hparam.s[e->hparam.len] = c;
				if (hdr.type!=HDR_OTHER_T && hdr.type!=HDR_ERROR_T)
				{
					LOG(L_INFO,"INFO:xprint: xl_parse_format: using "
						"hdr type (%d) instead of <%.*s>\n",
						hdr.type, e->hparam.len, e->hparam.s);
					e->hparam.len = hdr.type;
					e->hparam.s = NULL;
				}
				e->itf = xl_get_header;
			break;
			case '<':
				p++;
				/* we expect a letter */
				if((*p < 'A' || *p > 'Z') && (*p < 'a' || *p > 'z'))
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] pos [%d]\n", s, (int)(p-s));
					goto error;
				}
				e->hparam.s = p;
				while(*p && *p!='>' && *p!='[')
					p++;
				if(*p == '\0')
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] expecting '>' after position [%d]\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				e->hparam.len = p - e->hparam.s;
				/* check if we have index */
				if(*p == '[')
				{
					p++;
					if(*p=='-')
					{
						p++;
						if(*p!='1')
						{
							LOG(L_ERR, "xprint: xl_parse_format: error"
								" parsing format [%s] -- only -1 is accepted"
								" as a negative index\n", s);
								goto error;
						}
						e->hindex = -1;
						p++;
					}
					else
					{
						while(*p>='0' && *p<='9')
						{
							e->hindex = e->hindex * 10 + *p - '0';
							p++;
						}
					}
					if(*p != ']')
					{
						LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
							" [%s] expecting ']' after position [%d]\n", s,
							(int)(e->hparam.s - s + e->hparam.len));
						goto error;
					}
					p++;
				}
				if(*p != '>')
				{
					LOG(L_ERR, "xprint: xl_parse_format: error parsing format"
						" [%s] expecting '>' after position [%d]!\n", s,
						(int)(e->hparam.s-s));
					goto error;
				}

				DBG("xprint: xl_parse_format: AVP [%.*s] index [%d]\n",
						e->hparam.len, e->hparam.s, e->hindex);

				e->itf = xl_get_avp;
			break;
			case '$':
				p++;
				name.s=p;
				while ( (*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9') || (*p=='_') || (*p=='+') || (*p=='-') || (*p=='[') || (*p==']') || (*p=='.') ) p++;
				name.len=p-name.s;
				p--;
				if (parse_avp_name(&name, &avp_flags, &avp_name, &avp_index) < 0) {
					ERR("error while parsing AVP name\n");
					goto error;
				}
				e->itf = xl_get_avp;
				e->hflags=avp_flags;
				e->hparam.s=name.s;
				e->hparam.len=name.len;
				e->hindex=avp_index;
				DBG("flags %x  name %.*s  index %d\n", avp_flags, avp_name.s.len, avp_name.s.s, avp_index);
				break;
			case '@':
					/* fill select structure and call resolve_select */
				DBG("xprint: xl_parse_format: @\n");
				if (shm)
					n=shm_parse_select(&p, &sel);
				else
					n=parse_select(&p, &sel);
				if (n<0) {
					ERR("xprint: xl_parse_format: parse_select returned error\n");
					goto error;
				}
				e->itf = xl_get_select;
				e->hparam.s = (char*)sel;
				e->free_f = (shm) ? xl_shm_free_select : xl_free_select;
				p--;
				break;
			case '%':
				e->itf = xl_get_percent;
				break;
			case ' ':	/* enables spaceless terminating of avp, e.g. "blah%$avp% text goes on" */
			case '|':
				e->itf = xl_get_empty;
				break;
			case '[':
				range = &e->hindex;
				e->itf = xl_get_range;
				while (1) {
					p++;
					if (((*p) >= '0') && ((*p) <= '9')) {
						(*range) *= 10;
						(*range) += (*p) - '0';

					} else if ((*p) == '-') {
						if (range == &e->hindex) {
							range = &e->hflags;
						} else {
							ERR("xprint: xl_parse_format: syntax error in the range specification\n");
							goto error;
						}

					} else if ((*p) == ']') {
						if (range == &e->hindex) {
							/* no range, only a single number */
							e->hflags = e->hindex;
						} else if (e->hflags == 0) {
							/* only the left side is defined */
							e->hflags = -1;
						} else if (e->hindex > e->hflags) {
							ERR("xprint: xl_parse_format: syntax error in the range specification\n");
							goto error;
						}
						break;

					} else {
						ERR("xprint: xl_parse_format: syntax error in the range specification\n");
						goto error;
					}
				}
				break;
			default:
				e->itf = xl_get_null;
		}

cont:
		if(*p == '\0')
			break;
		p++;
	}
	DBG("XLOG: xl_parse_format: format parsed OK: [%d] items\n", n);

	return 0;

error:
	_xl_elog_free_all(*el, shm);
	*el = NULL;
	return -1;
}
Example #4
0
int add_avp_galias_str(char *alias_definition)
{
	int_str avp_name;
	char *s;
	str  name;
	str  alias;
	int  type;

	s = alias_definition;
	while(*s && isspace((int)*s))
		s++;

	while (*s) {
		/* parse alias name */
		alias.s = s;
		while(*s && *s!=';' && !isspace((int)*s) && *s!='=')
			s++;
		if (alias.s==s || *s==0 || *s==';')
			goto parse_error;
		alias.len = s-alias.s;
		while(*s && isspace((int)*s))
			s++;
		/* equal sign */
		if (*s!='=')
			goto parse_error;
		s++;
		while(*s && isspace((int)*s))
			s++;
		/* avp name */
		name.s = s;
		while(*s && *s!=';' && !isspace((int)*s))
			s++;
		if (name.s==s)
			goto parse_error;
		name.len = s-name.s;
		while(*s && isspace((int)*s))
			s++;
		/* check end */
		if (*s!=0 && *s!=';')
			goto parse_error;
		if (*s==';') {
			for( s++ ; *s && isspace((int)*s) ; s++ );
			if (*s==0)
				goto parse_error;
		}

		if (parse_avp_name( &name, &type, &avp_name)!=0) {
			LM_ERR("<%.*s> not a valid AVP name\n", name.len, name.s);
			goto error;
		}

		if (add_avp_galias( &alias, type, avp_name)!=0) {
			LM_ERR("add global alias failed\n");
			goto error;
		}
	} /*end while*/

	return 0;
parse_error:
	LM_ERR("parse error in <%s> around pos %ld\n", 
			alias_definition, (long)(s-alias_definition));
error:
	return -1;
}