示例#1
0
char *parse_addr_spec(char *const buffer, const char *const end,
		struct to_body *const to_b, const int allow_comma_sep)
{
	int status;
	int saved_status;
	char *tmp, *foo;

	saved_status = START_TO; /* fixes gcc 4.x warning */
	status = START_TO;
	memset(to_b, 0, sizeof(struct to_body));
	to_b->error = PARSE_OK;
	foo = 0;

	for(tmp = buffer; tmp < end; tmp++) {
		switch(*tmp) {
			case ' ':
			case '\t':
				switch(status) {
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now =' '*/
						status = saved_status;
						break;
					case URI_ENCLOSED:
						to_b->uri.len = tmp - to_b->uri.s;
						status = E_URI_ENCLOSED;
						break;
					case URI_OR_TOKEN:
						foo = tmp;
						status = MAYBE_URI_END;
						break;
					case DISPLAY_TOKEN:
						foo = tmp;
						status = DISPLAY_TOKEN_SP;
						break;
				}
				break;
			case '\n':
				switch(status) {
					case URI_OR_TOKEN:
						foo = tmp;
						status = MAYBE_URI_END;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN_SP:
					case E_DISPLAY_QUOTED:
					case END:
						saved_status = status;
						status = F_LF;
						break;
					case DISPLAY_TOKEN:
						foo = tmp;
						saved_status = DISPLAY_TOKEN_SP;
						status = F_LF;
						break;
					case F_CR:
						status = F_CRLF;
						break;
					case F_CRLF:
					case F_LF:
						status = saved_status;
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case '\r':
				switch(status) {
					case URI_OR_TOKEN:
						foo = tmp;
						status = MAYBE_URI_END;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN_SP:
					case E_DISPLAY_QUOTED:
					case END:
						saved_status = status;
						status = F_CR;
						break;
					case DISPLAY_TOKEN:
						foo = tmp;
						saved_status = DISPLAY_TOKEN_SP;
						status = F_CR;
						break;
					case F_CRLF:
					case F_CR:
					case F_LF:
						status = saved_status;
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case 0:
				switch(status) {
					case URI_OR_TOKEN:
					case MAYBE_URI_END:
						to_b->uri.len = tmp - to_b->uri.s;
					case END:
						saved_status = status = END;
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case '\\':
				switch(status) {
					case DISPLAY_QUOTED:
						tmp++; /* jump over next char */
						break;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case '<':
				switch(status) {
					case START_TO:
						to_b->body.s = tmp;
						status = S_URI_ENCLOSED;
						break;
					case DISPLAY_QUOTED:
						break;
					case E_DISPLAY_QUOTED:
						status = S_URI_ENCLOSED;
						break;
					case URI_OR_TOKEN:
					case DISPLAY_TOKEN:
						to_b->display.len = tmp - to_b->display.s;
						status = S_URI_ENCLOSED;
						break;
					case DISPLAY_TOKEN_SP:
					case MAYBE_URI_END:
						to_b->display.len = foo - to_b->display.s;
						status = S_URI_ENCLOSED;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case '>':
				switch(status) {
					case DISPLAY_QUOTED:
						break;
					case URI_ENCLOSED:
						to_b->uri.len = tmp - to_b->uri.s;
					case E_URI_ENCLOSED:
						status = END;
						foo = 0;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), ZSW(buffer));
						goto error;
				}
				break;
			case '"':
				switch(status) {
					case START_TO:
						to_b->body.s = tmp;
						to_b->display.s = tmp;
						status = DISPLAY_QUOTED;
						break;
					case DISPLAY_QUOTED:
						status = E_DISPLAY_QUOTED;
						to_b->display.len = tmp - to_b->display.s + 1;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), buffer);
						goto error;
				}
				break;
			case ';':
				switch(status) {
					case DISPLAY_QUOTED:
					case URI_ENCLOSED:
						break;
					case URI_OR_TOKEN:
						foo = tmp;
					case MAYBE_URI_END:
						to_b->uri.len = foo - to_b->uri.s;
					case END:
						to_b->body.len = tmp - to_b->body.s;
						tmp = parse_to_param(
								tmp, end, to_b, allow_comma_sep, &saved_status);
						goto endofheader;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_ERR("unexpected char [%c] in status %d: [%.*s] .\n",
								*tmp, status, (int)(tmp - buffer), buffer);
						goto error;
				}
				break;
			case ',':
				if(allow_comma_sep) {
					switch(status) {
						case DISPLAY_QUOTED:
						case URI_ENCLOSED:
							break;
						case URI_OR_TOKEN:
							foo = tmp;
						case MAYBE_URI_END:
							to_b->uri.len = foo - to_b->uri.s;
						case END:
							to_b->body.len = tmp - to_b->body.s;
							saved_status = END;
							goto endofheader;
						case F_CRLF:
						case F_LF:
						case F_CR:
							/*previous=crlf and now !=' '*/
							goto endofheader;
						default:
							LM_ERR("unexpected char [%c] in status %d: [%.*s] "
									".\n",
									*tmp, status, (int)(tmp - buffer), buffer);
							goto error;
					}
					break;
				}
			/* If commas not allowed treat as a default character */
			default:
				switch(status) {
					case START_TO:
						to_b->uri.s = to_b->body.s = tmp;
						status = URI_OR_TOKEN;
						to_b->display.s = tmp;
						break;
					case S_URI_ENCLOSED:
						to_b->uri.s = tmp;
						status = URI_ENCLOSED;
						break;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN_SP:
						status = DISPLAY_TOKEN;
					case DISPLAY_QUOTED:
					case DISPLAY_TOKEN:
					case URI_ENCLOSED:
					case URI_OR_TOKEN:
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_DBG("spitting out [%c] in status %d\n", *tmp,
								status);
						goto error;
				}
		} /*char switch*/
	}	 /*for*/

	/* Reached end of buffer */
	switch(status) {
		case URI_OR_TOKEN:
		case MAYBE_URI_END:
		case END:
			saved_status = status;
			foo = tmp;
	}

endofheader:
	if(to_b->display.len == 0)
		to_b->display.s = 0;
	status = saved_status;
	LM_DBG("end of header reached, state=%d\n", status);
	/* check if error*/
	switch(status) {
		case URI_OR_TOKEN:
		case MAYBE_URI_END:
			to_b->uri.len = foo - to_b->uri.s;
		case END:
			to_b->body.len = tmp - to_b->body.s;
		case E_PARA_VALUE:
			break;
		default:
			LM_ERR("invalid To -  unexpected "
					"end of header in state %d\n",
					status);
			goto error;
	}
	return tmp;

error:
	free_to_params(to_b);
	to_b->error = PARSE_ERROR;
	return tmp;
}
示例#2
0
char* parse_to(char* buffer, char *end, struct to_body *to_b)
{
	int status;
	int saved_status;
	char  *tmp;
	char  *end_mark;

	status=START_TO;
	saved_status=START_TO;
	to_b->error=PARSE_OK;
	to_b->uri.len = 0;
	to_b->uri.s= 0;
	to_b->display.len = 0;
	to_b->display.s = 0;
	end_mark=0;

	for( tmp=buffer; tmp<end; tmp++)
	{
		switch(*tmp)
		{
			case ' ':
			case '\t':
				switch (status)
				{
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now =' '*/
						status=saved_status;
						break;
					case URI_ENCLOSED:
						to_b->uri.len = tmp - to_b->uri.s;
						status = E_URI_ENCLOSED;
						break;
					case URI_OR_TOKEN:
						status = MAYBE_URI_END;
						end_mark = tmp;
						break;
					case DISPLAY_TOKEN:
						end_mark = tmp;
						status = DISPLAY_TOKEN2;
						break;
				}
				break;
			case '\n':
				switch (status)
				{
					case URI_OR_TOKEN:
						end_mark = tmp;
						status = MAYBE_URI_END;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN:
					case DISPLAY_TOKEN2:
					case E_DISPLAY_QUOTED:
					case END:
						saved_status=status;
						status=F_LF;
						break;
					case F_CR:
						status=F_CRLF;
						break;
					case F_CRLF:
					case F_LF:
						status=saved_status;
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case '\r':
				switch (status)
				{
					case URI_OR_TOKEN:
						end_mark = tmp;
						status = MAYBE_URI_END;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN:
					case DISPLAY_TOKEN2:
					case E_DISPLAY_QUOTED:
					case END:
						saved_status=status;
						status=F_CR;
						break;
					case F_CRLF:
					case F_CR:
					case F_LF:
						status=saved_status;
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case 0:
				switch (status)
				{
					case URI_OR_TOKEN:
					case MAYBE_URI_END:
						to_b->uri.len = tmp - to_b->uri.s;
					case END:
						saved_status = status = END;
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case '\\':
				switch (status)
				{
					case DISPLAY_QUOTED:
						tmp++; /* jump over next char */
						break;
					default:
						goto parse_error;
				}
				break;
			case '<':
				switch (status)
				{
					case START_TO:
						to_b->body.s=tmp;
						status = S_URI_ENCLOSED;
						break;
					case DISPLAY_QUOTED:
						break;
					case E_DISPLAY_QUOTED:
						status = S_URI_ENCLOSED;
						break;
					case URI_OR_TOKEN:
					case DISPLAY_TOKEN:
						end_mark = tmp;
					case DISPLAY_TOKEN2:
					case MAYBE_URI_END:
						to_b->display.len=end_mark-to_b->display.s;
						status = S_URI_ENCLOSED;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case '>':
				switch (status)
				{
					case DISPLAY_QUOTED:
						break;
					case URI_ENCLOSED:
						to_b->uri.len = tmp - to_b->uri.s;
					case E_URI_ENCLOSED:
						status = END;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case '"':
				switch (status)
				{
					case START_TO:
						to_b->body.s = tmp;
						to_b->display.s = tmp;
						status = DISPLAY_QUOTED;
						break;
					case DISPLAY_QUOTED:
						status = E_DISPLAY_QUOTED;
						to_b->display.len = tmp-to_b->display.s+1;
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			case ';' :
				switch (status)
				{
					case DISPLAY_QUOTED:
					case DISPLAY_TOKEN:
					case URI_ENCLOSED:
						break;
					case URI_OR_TOKEN:
						end_mark = tmp;
					case MAYBE_URI_END:
						to_b->uri.len = end_mark - to_b->uri.s;
					case END:
						to_b->body.len = tmp-to_b->body.s;
						tmp = parse_to_param(tmp,end,to_b,&saved_status);
						goto endofheader;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						goto parse_error;
				}
				break;
			default:
				switch (status)
				{
					case START_TO:
						to_b->uri.s = to_b->body.s = tmp;
						status = URI_OR_TOKEN;
						to_b->display.s=tmp;
						break;
					case S_URI_ENCLOSED:
						to_b->uri.s=tmp;
						status=URI_ENCLOSED;
						break;
					case MAYBE_URI_END:
					case DISPLAY_TOKEN2:
						status = DISPLAY_TOKEN;
					case DISPLAY_QUOTED:
					case DISPLAY_TOKEN:
					case URI_ENCLOSED:
					case URI_OR_TOKEN:
						break;
					case F_CRLF:
					case F_LF:
					case F_CR:
						/*previous=crlf and now !=' '*/
						goto endofheader;
					default:
						LM_DBG("spitting out [%c] in status %d\n",
						*tmp,status );
						goto error;
				}
		}/*char switch*/
	}/*for*/

endofheader:
	if (to_b->display.len==0) to_b->display.s=0;
	status=saved_status;
	LM_DBG("end of header reached, state=%d\n", status);
	/* check if error*/
	switch(status){
		case MAYBE_URI_END:
			to_b->uri.len = end_mark - to_b->uri.s;
		case END:
			to_b->body.len = tmp - to_b->body.s;
		case E_PARA_VALUE:
			break;
		default:
			LM_ERR("unexpected end of header in state %d\n", status);
			goto error;
	}

	LM_DBG("display={%.*s}, ruri={%.*s}\n",
		to_b->display.len, ZSW(to_b->display.s),
		to_b->uri.len, ZSW(to_b->uri.s));
	return tmp;

parse_error:
	LM_ERR("unexpected char [%c] in status %d: <<%.*s>> .\n",
		*tmp,status, (int)(tmp-buffer), buffer);
error:
	to_b->error=PARSE_ERROR;
	return tmp;

}
示例#3
0
char* parse_to(char* buffer, char *end, struct to_body *to_b)
{
    int status;
    int saved_status;
    char  *tmp,*foo;

    status=START_TO;
    saved_status=START_TO;
    to_b->error=PARSE_OK;
    to_b->uri.len = 0;
    to_b->uri.s= 0;
    to_b->display.len = 0;
    to_b->display.s = 0;
    foo=0;

    for( tmp=buffer; tmp<end; tmp++)
    {
        switch(*tmp)
        {
        case ' ':
        case '\t':
            switch (status)
            {
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now =' '*/
                status=saved_status;
                break;
            case URI_ENCLOSED:
                to_b->uri.len = tmp - to_b->uri.s;
                status = E_URI_ENCLOSED;
                break;
            case URI_OR_TOKEN:
                foo = tmp;
                status = MAYBE_URI_END;
                break;
            }
            break;
        case '\n':
            switch (status)
            {
            case URI_OR_TOKEN:
                foo = tmp;
                status = MAYBE_URI_END;
            case MAYBE_URI_END:
            case DISPLAY_TOKEN:
            case E_DISPLAY_QUOTED:
            case END:
                saved_status=status;
                status=F_LF;
                break;
            case F_CR:
                status=F_CRLF;
                break;
            case F_CRLF:
            case F_LF:
                status=saved_status;
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case '\r':
            switch (status)
            {
            case URI_OR_TOKEN:
                foo = tmp;
                status = MAYBE_URI_END;
            case MAYBE_URI_END:
            case DISPLAY_TOKEN:
            case E_DISPLAY_QUOTED:
            case END:
                saved_status=status;
                status=F_CR;
                break;
            case F_CRLF:
            case F_CR:
            case F_LF:
                status=saved_status;
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case 0:
            switch (status)
            {
            case URI_OR_TOKEN:
            case MAYBE_URI_END:
                to_b->uri.len = tmp - to_b->uri.s;
            case END:
                saved_status = status = END;
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case '\\':
            switch (status)
            {
            case DISPLAY_QUOTED:
                tmp++; /* jump over next char */
                break;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case '<':
            switch (status)
            {
            case START_TO:
                to_b->body.s=tmp;
                status = S_URI_ENCLOSED;
                break;
            case DISPLAY_QUOTED:
                break;
            case E_DISPLAY_QUOTED:
                status = S_URI_ENCLOSED;
                break;
            case URI_OR_TOKEN:
            case DISPLAY_TOKEN:
            case MAYBE_URI_END:
                to_b->display.len=foo-to_b->display.s;
                status = S_URI_ENCLOSED;
                break;
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now !=' '*/
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case '>':
            switch (status)
            {
            case DISPLAY_QUOTED:
                break;
            case URI_ENCLOSED:
                to_b->uri.len = tmp - to_b->uri.s;
            case E_URI_ENCLOSED:
                status = END;
                foo = 0;
                break;
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now !=' '*/
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), ZSW(buffer));
                goto error;
            }
            break;
        case '"':
            switch (status)
            {
            case START_TO:
                to_b->body.s = tmp;
                to_b->display.s = tmp;
                status = DISPLAY_QUOTED;
                break;
            case DISPLAY_QUOTED:
                status = E_DISPLAY_QUOTED;
                to_b->display.len = tmp-to_b->display.s+1;
                break;
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now !=' '*/
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), buffer);
                goto error;
            }
            break;
        case ';' :
            switch (status)
            {
            case DISPLAY_QUOTED:
            case URI_ENCLOSED:
                break;
            case URI_OR_TOKEN:
                foo = tmp;
            case MAYBE_URI_END:
                to_b->uri.len = foo - to_b->uri.s;
            case END:
                to_b->body.len = tmp-to_b->body.s;
                tmp = parse_to_param(tmp,end,to_b,&saved_status);
                goto endofheader;
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now !=' '*/
                goto endofheader;
            default:
                LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
                     "in status %d: <<%.*s>> .\n",
                     *tmp,status, (int)(tmp-buffer), buffer);
                goto error;
            }
            break;
        default:
            switch (status)
            {
            case START_TO:
                to_b->uri.s = to_b->body.s = tmp;
                status = URI_OR_TOKEN;
                to_b->display.s=tmp;
                break;
            case S_URI_ENCLOSED:
                to_b->uri.s=tmp;
                status=URI_ENCLOSED;
                break;
            case MAYBE_URI_END:
                status = DISPLAY_TOKEN;
            case DISPLAY_QUOTED:
            case DISPLAY_TOKEN:
            case URI_ENCLOSED:
            case URI_OR_TOKEN:
                break;
            case F_CRLF:
            case F_LF:
            case F_CR:
                /*previous=crlf and now !=' '*/
                goto endofheader;
            default:
                DBG("DEBUG:parse_to: spitting out [%c] in status %d\n",
                    *tmp,status );
                goto error;
            }
        }/*char switch*/
    }/*for*/

endofheader:
    if (to_b->display.len==0) to_b->display.s=0;
    status=saved_status;
    DBG("DEBUG:parse_to:end of header reached, state=%d\n", status);
    /* check if error*/
    switch(status) {
    case MAYBE_URI_END:
        to_b->uri.len = foo - to_b->uri.s;
    case END:
        to_b->body.len = tmp - to_b->body.s;
    case E_PARA_VALUE:
        break;
    default:
        LOG(L_ERR, "ERROR: parse_to: invalid To -  unexpected "
            "end of header in state %d\n", status);
        goto error;
    }
    return tmp;

error:
    to_b->error=PARSE_ERROR;
    return tmp;

}