Exemple #1
0
 /* 
  * Parse comma separated list of methods pointed by _body and assign their
  * enum bits to _methods.  Returns 1 on success and 0 on failure.
  */
 int parse_methods(str* _body, unsigned int* _methods)
 {
 	str next;
 	unsigned int method;
	
	method=0; /* fixes silly gcc 4.x warning */
 
	if (!_body || !_methods) {
		LOG(L_ERR, "parse_methods: Invalid parameter value\n");
		return 0;
	}

	next.len = _body->len;
	next.s = _body->s;
 
 	trim_leading(&next);
 
 	if (next.len == 0) {
 		LOG(L_ERR, "ERROR: parse_methods: Empty body\n");
 		return 0;
 	}

  	*_methods = 0;
 
 	while (1) {
 		if (parse_method(&next, &method)) {
 			*_methods |= method;
 		} else {
 			LOG(L_ERR, "ERROR: parse_methods: Invalid method\n");
 			return 0;
 		}
		
 		trim_leading(&next);
 		if (next.len) {
 			if (next.s[0] == ',') {
 				next.len--;
 				next.s++;
 				trim_leading(&next);
 				if (next.len == 0) {
 					LOG(L_ERR, "ERROR: parse_methods: Method expected\n");
 					return 0;
 				}
 			} else {
 				LOG(L_ERR, "ERROR: parse_methods: Comma expected\n");
 				return 0;
 			}
 		} else {
 			break;
 		}
 	}

 	return 1;
 }
Exemple #2
0
static inline int contact_parser(char* _s, int _l, contact_body_t* _c)
{
	str tmp;

	tmp.s = _s;
	tmp.len = _l;

	trim_leading(&tmp);

	if (tmp.len == 0) {
		LM_ERR("empty body\n");
		return -1;
	}

	if (tmp.s[0] == '*') {
		_c->star = 1;
		if (tmp.len!=1) {
			LM_ERR("invalid START Contact header (more than START only)\n");
			return -2;
		}
	} else {
		if (parse_contacts(&tmp, &(_c->contacts)) < 0) {
			LM_ERR("failed to parse contacts\n");
			return -3;
		}
	}

	return 0;
}
Exemple #3
0
static inline int contact_parser(char* _s, int _l, contact_body_t* _c)
{
	str tmp;

	tmp.s = _s;
	tmp.len = _l;

	trim_leading(&tmp);

	if (tmp.len == 0) {
		LOG(L_ERR, "contact_parser(): Empty body\n");
		return -1;
	}

	if (tmp.s[0] == '*') {
		_c->star = 1;
	} else {
		if (parse_contacts(&tmp, &(_c->contacts)) < 0) {
			LOG(L_ERR, "contact_parser(): Error while parsing contacts\n");
			return -2;
		}
	}

	return 0;
}
Exemple #4
0
void xhttp_rpc_get_next_arg(rpc_ctx_t* ctx, str *arg)
{
    int i;

    trim_leading(&ctx->arg2scan);

    if (ctx->arg2scan.len<=0) {
        *arg = XHTTP_RPC_NULL_ARG;
        return;
    }
    if (ctx->arg2scan.len==1 && ctx->arg2scan.s[0]=='\0') {
        *arg = XHTTP_RPC_NULL_ARG;
        return;
    }
    else {
        *arg = ctx->arg2scan;
        for(i=1; i<arg->len-1; i++) {
            if(arg->s[i]==' '||arg->s[i]=='\t'||
                    arg->s[i]=='\r'||arg->s[i]=='\n')
                break;
        }
        arg->len = i;
        arg->s[i] = '\0';
        i++;
        ctx->arg2scan.s += i;
        ctx->arg2scan.len -= i;
    }
    return;
}
Exemple #5
0
/*
 * Parse comma separated list of methods pointed by _body and assign their
 * enum bits to _methods.  Returns 0 on success and -1 on failure.
 */
int parse_methods(str* _body, unsigned int* _methods)
{
	str next;
	char *p;
	char *p0;
	unsigned int method;

	if (!_body || !_methods) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	next.len = _body->len;
	next.s = _body->s;

	trim_leading(&next);

	*_methods = 0;
	if (next.len == 0) {
		goto done;
	}

	method = 0;
	p = next.s;

	while (p<next.s+next.len) {
		if((p0=parse_method(p, next.s+next.len, &method))!=NULL) {
			*_methods |= method;
			p = p0;
		} else {
			LM_ERR("invalid method [%.*s]\n", next.len, next.s);
			return -1;
		}

		while(p<next.s+next.len && (*p==' ' || *p=='\t'
					|| *p=='\r' || *p=='\n'))
			p++;
		if(p>=next.s+next.len || *p == '\0')
			goto done;


		if (*p == ',')
		{
			p++;
			while(p<next.s+next.len && (*p==' ' || *p=='\t'
					|| *p=='\r' || *p=='\n'))
				p++;
			if(p>=next.s+next.len)
				goto done;
		} else {
			LM_ERR("comma expected\n");
			return -1;
		}
	}

done:
	LM_DBG("methods 0x%X\n", *_methods);
	return 0;
}
Exemple #6
0
int read_float(FILE *f, char *config_path, float *result) {
    /*
     * Reads the given float from config.
     *
     * Returns -1 if the value could not be found, 0 on success
     * and a positive integer on failure.
     */

    int success;
    uint8_t temp;

    success = seek_definition(f, config_path);
    if (success != 0)
        return success;

    temp = fgetc(f);
    if (temp != 1)
        return 1;

    temp = fgetc(f);

    while (fgetc(f) != 0);

    if (temp == 2) {
        // Convert integer to float
        int32_t int_value;

        fread(&int_value, 4, 1, f);
        *result = (float)int_value;
    } else if (temp == 0) {
        // Try to parse "rad X" strings
        char string_value[512];
        char *endptr;
        long fp;

        fp = ftell(f);
        if (fgets(string_value, sizeof(string_value), f) == NULL)
            return 2;
        fseek(f, fp + strlen(string_value) + 1, SEEK_SET);

        trim_leading(string_value, sizeof(string_value));
        lower_case(string_value);

        if (strncmp(string_value, "rad ", 4) != 0)
            return 3;

        *result = strtof(string_value + 4, &endptr);
        if (strlen(endptr) > 0)
            return 4;

        *result *= RAD2DEG;
    } else {
        fread(result, 4, 1, f);
    }

    return 0;
}
Exemple #7
0
/*
 * We support Digest authentication only
 *
 * Returns:
 *  0 - if everything is OK
 * -1 - Error while parsing
 *  1 - Unknown scheme
 */
int parse_digest_cred(str* _s, dig_cred_t* _c)
{
	str tmp;

	     /* Make a temporary copy, we are
	      * going to modify it 
	      */
	tmp.s = _s->s;
	tmp.len = _s->len;

	     /* Remove any leading spaces, tabs, \r and \n */
	trim_leading(&tmp);

	     /* Check the string length */
	if (tmp.len < (DIG_LEN + 1)) return 1; /* Too short, unknown scheme */

	     /* Now test, if it is digest scheme, since it is the only
	      * scheme we are able to parse here
	      */
	if (!strncasecmp(tmp.s, DIGEST_SCHEME, DIG_LEN) &&
	    ((tmp.s[DIG_LEN] == ' ') ||     /* Test for one of LWS chars */
	     (tmp.s[DIG_LEN] == '\r') || 
	     (tmp.s[DIG_LEN] == 'n') || 
	     (tmp.s[DIG_LEN] == '\t') ||
	     (tmp.s[DIG_LEN] == ','))) {
		     /* Scheme is Digest */
		tmp.s += DIG_LEN + 1;
		tmp.len -= DIG_LEN + 1;
		
		     /* Again, skip all white-spaces */
		trim_leading(&tmp);

		     /* And parse digest parameters */
		if (parse_digest_params(&tmp, _c) < 0) {
			return -2; /* We must not return -1 in this function ! */
		} else {
			return 0;
		}
	} else {
		return 1; /* Unknown scheme */
	}
}
Exemple #8
0
/*
 * Parse a digest parameter
 */
static inline int parse_digest_param(str* _s, dig_cred_t* _c)
{
	dig_par_t t;
	str* ptr;
	str dummy;

	     /* Get type of the parameter */
	if (parse_param_name(_s, &t) < 0) {
		return -1;
	}

	_s->s++;  /* skip = */
	_s->len--;

	     /* Find the begining of body */
	trim_leading(_s);

	if (_s->len == 0) {
		return -2;
	}

	     /* Decide in which attribute the
	      * body content will be stored
	      */
	switch(t) {
	case PAR_USERNAME:  ptr = &_c->username.whole;  break;
	case PAR_REALM:     ptr = &_c->realm;           break;
	case PAR_NONCE:     ptr = &_c->nonce;           break;
	case PAR_URI:       ptr = &_c->uri;             break;
	case PAR_RESPONSE:  ptr = &_c->response;        break;
	case PAR_CNONCE:    ptr = &_c->cnonce;          break;
	case PAR_OPAQUE:    ptr = &_c->opaque;          break;
	case PAR_QOP:       ptr = &_c->qop.qop_str;     break;
	case PAR_NC:        ptr = &_c->nc;              break;
	case PAR_ALGORITHM: ptr = &_c->alg.alg_str;     break;
	case PAR_OTHER:     ptr = &dummy;               break;
	default:            ptr = &dummy;               break;
	}

	     /* If the first character is quote, it is
	      * a quoted string, otherwise it is a token
	      */
	if (_s->s[0] == '\"') {
		if (parse_quoted(_s, ptr) < 0) {
			return -3;
		}
	} else {
		if (parse_token(_s, ptr) < 0) {
			return -4;
		}
	}
	
	return 0;
}
Exemple #9
0
/** initializes a net structure from a string.
 * @param dst - net structure that will be filled
 * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak".
 * @return -1 on error, 0 on succes
 */
int mk_net_str(struct net* dst, str* s)
{
	struct ip_addr* t;
	char* p;
	struct ip_addr ip;
	str addr;
	str mask;
	unsigned int bitlen;
	
	/* test for ip only */
	t = str2ip(s);
	if (unlikely(t == 0))
		t = str2ip6(s);
	if (likely(t))
		return mk_net_bitlen(dst, t, t->len*8);
	/* not a simple ip, maybe an ip/netmask pair */
	p = q_memchr(s->s, '/', s->len);
	if (likely(p)) {
		addr.s = s->s;
		addr.len = (int)(long)(p - s->s);
		mask.s = p + 1;
		mask.len = s->len - (addr.len + 1);
		/* allow '/' enclosed by whitespace */
		trim_trailing(&addr);
		trim_leading(&mask);
		t = str2ip(&addr);
		if (likely(t)) {
			/* it can be a number */
			if (str2int(&mask, &bitlen) == 0)
				return mk_net_bitlen(dst, t, bitlen);
			ip = *t;
			t = str2ip(&mask);
			if (likely(t))
				return mk_net(dst, &ip, t);
			/* error */
			return -1;
		}
		else {
			t = str2ip6(&addr);
			if (likely(t)) {
				/* it can be a number */
				if (str2int(&mask, &bitlen) == 0)
					return mk_net_bitlen(dst, t, bitlen);
				ip = *t;
				t = str2ip6(&mask);
				if (likely(t))
					return mk_net(dst, &ip, t);
				/* error */
				return -1;
			}
		}
	}
	return -1;
}
Exemple #10
0
int seek_definition(FILE *f, char *config_path) {
    /*
     * Finds the definition of the given value, even if it is defined in a
     * parent class.
     *
     * Returns 0 on success, a positive integer on failure.
     */

    int success;

    // Try the direct way first
    fseek(f, 16, SEEK_SET);
    success = seek_config_path(f, config_path);
    if (success >= 0)
        return success;

    // No containing class
    if (strchr(config_path, '>') == NULL)
        return 1;

    // Try to find the definition
    int i;
    char containing[2048];
    char parent[2048];
    char value[2048];

    strncpy(containing, config_path, sizeof(containing));
    *(strrchr(containing, '>') - 1) = 0;
    for (i = strlen(containing) - 1; i >= 0 && containing[i] == ' '; i--)
        containing[i] = 0;

    fseek(f, 16, SEEK_SET);
    success = seek_config_path(f, containing);

    // Containing class doesn't even exist
    if (success < 0)
        return success;

    // Find parent of the containing class
    success = find_parent(f, containing, parent, sizeof(parent));
    if (success) {
        return success;
    }

    strncpy(value, strrchr(config_path, '>') + 1, sizeof(value));
    trim_leading(value, sizeof(value));

    strcat(parent, " >> ");
    strcat(parent, value);

    return seek_definition(f, parent);
}
static int check_ftag(struct sip_msg* msg, str* uri)
{
	param_hooks_t hooks;
	param_t* params;
	char* semi;
	struct to_body* from;
	str t;

	t = *uri;
	params = 0;
	semi = q_memchr(t.s, ';', t.len);
	if (!semi) {
		DBG("No ftag parameter found\n");
		return -1;
	}

	t.len -= semi - uri->s + 1;
	t.s = semi + 1;
	trim_leading(&t);

	if (parse_params(&t, CLASS_URI, &hooks, &params) < 0) {
		ERR("Error while parsing parameters\n");
		return -1;
	}

	if (!hooks.uri.ftag) {
		DBG("No ftag parameter found\n");
		goto err;
	}

	from = get_from(msg);

	if (!from || !from->tag_value.len || !from->tag_value.s) {
		DBG("No from tag parameter found\n");
		goto err;
	}

	if (from->tag_value.len == hooks.uri.ftag->body.len &&
	    !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) {
		DBG("Route ftag and From tag are same\n");
		free_params(params);
		return 0;
	} else {
		DBG("Route ftag and From tag are NOT same\n");
		free_params(params);
		return 1;
	}

 err:
	if (params) free_params(params);
	return -1;
}
Exemple #12
0
static inline void parse_word(str* _s, str* word)
{
  trim_leading(_s);
  word->len = 0;
  word->s = _s->s;
  for(; _s->len > 0; _s->len--, _s->s++) {
    switch(*(_s->s)) {
      case ' ':
      case '\t':
      case '\r':
      case '\n':
        return;

      default:
        word->len++;
        break;
    }
  }
}
Exemple #13
0
int etag_parser(char *_s, int _l, str *_e)
{
        char* end;

        _e->s = _s;
        _e->len = _l;

        trim_leading(_e);

        if (_e->len == 0) {
                LOG(L_ERR, "etag_parser(): Empty body\n");
                return -1;
        }

        end = skip_token(_e->s, _e->len);
        _e->len = end - _e->s;

	return 0;
}
Exemple #14
0
/*
 * Get CSeq number
 * Does not parse headers !!
 */
static inline int get_cseq_value(struct sip_msg* _m, unsigned int* _cs)
{
	str num;

	if (_m->cseq == 0) {
		LOG(L_ERR, "get_cseq_value(): CSeq header not found\n");
		return -1;
	}

	num.s = get_cseq(_m)->number.s;
	num.len = get_cseq(_m)->number.len;

	trim_leading(&num);
	if (str2int(&num, _cs) < 0) {
		LOG(L_ERR, "get_cseq_value(): Error while converting cseq number\n");
		return -2;
	}
	return 0;
}
Exemple #15
0
int parse_param_name(str* _s, dig_par_t* _type)
{
        register char* p;
        register int val;
	char* end;
	
	end = _s->s + _s->len;
	
	p = _s->s;
	val = READ(p);
	
	if (_s->len < 4) {
		goto other;
	}
	
        switch(LOWER_DWORD(val)) {
	FIRST_QUATERNIONS;
	default:
		PARSE_SHORT;
		goto other;
        }

 end:
	_s->len -= p - _s->s;
	_s->s = p;

	trim_leading(_s);
	if (_s->s[0] == '=') {
		return 0;
	}
	
 other:
	p = q_memchr(p, '=', end - p);
	if (!p) {
		return -1; /* Parse error */
	} else {
		*_type = PAR_OTHER;
		_s->len -= p - _s->s;
		_s->s = p;
		return 0;
	}
}
Exemple #16
0
/*
 * Parse Digest credentials parameter, one by one
 */
static inline int parse_digest_params(str* _s, dig_cred_t* _c)
{
	char* comma;

	do {
		     /* Parse the first parameter */
		if (parse_digest_param(_s, _c) < 0) {
			return -1;
		}
		
		     /* Try to find the next parameter */
		comma = q_memchr(_s->s, ',', _s->len);
		if (comma) {
			     /* Yes, there is another, 
			      * remove any leading white-spaces
			      * and let _s point to the next
			      * parameter name
			      */
			_s->len -= comma - _s->s + 1;
			_s->s = comma + 1;
			trim_leading(_s);
		}
	} while(comma); /* Repeat while there are next parameters */

	     /* Parse QOP body if the parameter was present */
	if (_c->qop.qop_str.s != 0) {
		parse_qop(&_c->qop);
	}

	     /* Parse algorithm body if the parameter was present */
	if (_c->alg.alg_str.s != 0) {
		parse_algorithm(&_c->alg);
	}

	if (_c->username.whole.s != 0) {
		parse_username(&_c->username);
	}

	return 0;
}
Exemple #17
0
int str_find_token(str *text, str *result, char delim)
{
	int i;
	if(text==NULL || result==NULL)
		return -1;
	if(text->s[0] == delim)
	{
		text->s += 1;
		text->len -= 1;
	}
	trim_leading(text);
	result->s = text->s;
	result->len = 0;
	for (i=0; i<text->len; i++)
	{
		if(result->s[i]==delim || result->s[i]=='\0'
				|| result->s[i]=='\r' || result->s[i]=='\n')
			return 0;
		result->len++;
	}
	return 0;
}
Exemple #18
0
static int scan_int(const char **in, int base, int width, int *res) {
	int neg = 0;
	int dst = 0;
	int ch;
	int i;
	int not_empty = 0;

	if (EOF == (ch = trim_leading(in))) {
		return EOF;
	}

	if ((ch == '-') || (ch == '+')) {
		neg = (ch == '-');
		scanchar(in);
	} else {
		dst = 0;
	}

	for (i = 0; (ch = (int) scanchar(in)) != EOF; i++) {
		if (!(base == 10 ? isdigit(ch) : isxdigit(ch)) || (0 == width)) {
			unscanchar(in, ch);
			/*end conversion*/
			break;
		}
		not_empty = 1;
		dst = base * dst + ch_to_digit(ch, base);
	}

	if (!not_empty) {
		return -1;
	}

	if (neg)
		dst = -dst;
	*res = dst;
	return 0;
}
Exemple #19
0
/*
 * Parse Route and Record-Route header fields
 */
int parse_rr(struct hdr_field* _h)
{
	rr_t* r, *last;
	str s;
	param_hooks_t hooks;

	if (!_h) {
		LOG(L_ERR, "parse_rr(): Invalid parameter value\n");
		return -1;
	}

	if (_h->parsed) {
		     /* Already parsed, return */
		return 0;
	}

	     /* Make a temporary copy of the string pointer */
	s.s = _h->body.s;
	s.len = _h->body.len;
	trim_leading(&s);

	last = 0;

	while(1) {
		     /* Allocate and clear rr stucture */
		r = (rr_t*)pkg_malloc(sizeof(rr_t));
		if (!r) {
			LOG(L_ERR, "parse_rr(): No memory left\n");
			goto error;
		}
		memset(r, 0, sizeof(rr_t));
		
		     /* Parse name-addr part of the header */
		if (parse_nameaddr(&s, &r->nameaddr) < 0) {
			LOG(L_ERR, "parse_rr(): Error while parsing name-addr\n");
			goto error;
		}
		r->len = r->nameaddr.len;

		     /* Shift just behind the closing > */
		s.s = r->nameaddr.name.s + r->nameaddr.len;  /* Point just behind > */
		s.len -= r->nameaddr.len;

		trim_leading(&s); /* Skip any whitechars */
		
		     /* Nothing left, finish */
		if (s.len == 0) goto ok;
		
		if (s.s[0] == ';') {         /* Contact parameter found */
			s.s++;
			s.len--;
			trim_leading(&s);
			
			if (s.len == 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}

			     /* Parse all parameters */
			if (parse_params(&s, CLASS_ANY, &hooks, &r->params) < 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}
			r->len = r->params->name.s + r->params->len - r->nameaddr.name.s;

			     /* Copy hooks */
			     /*r->r2 = hooks.rr.r2; */
			trim_leading(&s);
			if (s.len == 0) goto ok;
		}

		if (s.s[0] != ',') {
			LOG(L_ERR, "parse_rr(): Invalid character '%c', comma expected\n", s.s[0]);
			goto error;
		}

		     /* Next character is comma or end of header*/
		s.s++;
		s.len--;
		trim_leading(&s);

		if (s.len == 0) {
			LOG(L_ERR, "parse_rr(): Text after comma missing\n");
			goto error;
		}

		     /* Append the structure as last parameter of the linked list */
		if (!_h->parsed) _h->parsed = (void*)r;
		if (last) last->next = r;
		last = r;
	}

 error:
	if (r) pkg_free(r);
	free_rr((rr_t**)&_h->parsed); /* Free any contacts created so far */
	return -1;

 ok:
	if (!_h->parsed) _h->parsed = (void*)r;
	if (last) last->next = r;
	return 0;
}
Exemple #20
0
int event_parser(char* s, int len, event_t* e)
{
	int i;
	str tmp;
	char* end;
	param_hooks_t* phooks = NULL;
	enum pclass pclass = CLASS_ANY;

	if (e == NULL) {
		ERR("event_parser: Invalid parameter value\n");
		return -1;
	}

	tmp.s = s;
	tmp.len = len;
	trim_leading(&tmp);

	if (tmp.len == 0) {
		LOG(L_ERR, "event_parser: Empty body\n");
		return -1;
	}

	e->name.s = tmp.s;
	end = skip_token(tmp.s, tmp.len);
	e->name.len = end - tmp.s;

	e->type = EVENT_OTHER;
	for(i = 0; events[i].name.len; i++) {
		if (e->name.len == events[i].name.len &&
			!strncasecmp(e->name.s, events[i].name.s, e->name.len)) {
			e->type = events[i].type;
			break;
		}
	}

	tmp.len -= end - tmp.s;
	tmp.s = end;
	trim_leading(&tmp);

	e->params.list = NULL;
	
	if (tmp.len && (tmp.s[0] == ';')) {
		/* Shift the semicolon and skip any leading whitespace, this is needed
		 * for parse_params to work correctly. */
		tmp.s++; tmp.len--;
		trim_leading(&tmp);
		if (!tmp.len) return 0;

		/* We have parameters to parse */
		if (e->type == EVENT_DIALOG) {
			pclass = CLASS_EVENT_DIALOG;
			phooks = (param_hooks_t*)&e->params.hooks;
		}

		if (parse_params(&tmp, pclass, phooks, &e->params.list) < 0) {
			ERR("event_parser: Error while parsing parameters parameters\n");
			return -1;
		}
	}
	return 0;
}
Exemple #21
0
int event_parser(char* _s, int _l, event_t* _e)
{
	str tmp;
	char* end;
	param_hooks_t phooks;

	tmp.s = _s;
	tmp.len = _l;

	trim_leading(&tmp);

	if (tmp.len == 0) {
		LM_ERR("empty body\n");
		goto parse_error;
	}

	_e->text.s = tmp.s;

	end = skip_token(tmp.s, tmp.len);

	_e->text.len = end - tmp.s;

	if ((_e->text.len == PRES_STR_LEN) && 
		!strncasecmp(PRES_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_PRESENCE;
	} else if ((_e->text.len == PRES_XCAP_CHANGE_STR_LEN) && 
		   !strncasecmp(PRES_XCAP_CHANGE_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_XCAP_CHANGE;
	} else if ((_e->text.len == PRES_WINFO_STR_LEN) && 
		   !strncasecmp(PRES_WINFO_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_PRESENCE_WINFO;
	} else if ((_e->text.len == PRES_SIP_PROFILE_STR_LEN) && 
		   !strncasecmp(PRES_SIP_PROFILE_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_SIP_PROFILE;
	} else if ((_e->text.len == DIALOG_STR_LEN) && 
		   !strncasecmp(DIALOG_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_DIALOG;
	} else if ((_e->text.len == MWI_STR_LEN) && 
		   !strncasecmp(MWI_STR, tmp.s, _e->text.len)) {
		_e->parsed = EVENT_MWI;
	} else {
		_e->parsed = EVENT_OTHER;
	}

	if( (_e->text.len < tmp.len) && (*end)== ';')
	{
		str params_str;
		params_str.s = end+1;
		params_str.len = tmp.len- _e->text.len- 1;

		if (parse_params(&params_str, CLASS_ANY, &phooks, &_e->params)<0)
			goto parse_error;

		if(_e->parsed == EVENT_DIALOG && _e->params!= NULL
		&& _e->params->name.len== 3 &&
		strncasecmp(_e->params->name.s, "sla", 3)== 0 )
		{
			_e->parsed = EVENT_DIALOG_SLA;
		}
	} else {
		_e->params= NULL;
	}

	return 0;

parse_error:
	return -1;
}
Exemple #22
0
/*! \brief
 * Parse Route or Record-Route body
 */
static inline int do_parse_rr_body(char *buf, int len, rr_t **head)
{
	rr_t* r, *last;
	str s;
	param_hooks_t hooks;

	/* Make a temporary copy of the string pointer */
	if(buf==0 || len<=0)
	{
		DBG("parse_rr_body(): No body for record-route\n");
		*head = 0;
		return -2;
	}
	s.s = buf;
	s.len = len;
	trim_leading(&s);

	last = 0;

	while(1) {
		     /* Allocate and clear rr structure */
		r = (rr_t*)pkg_malloc(sizeof(rr_t));
		if (!r) {
			LOG(L_ERR, "parse_rr(): No memory left\n");
			goto error;
		}
		memset(r, 0, sizeof(rr_t));
		
		     /* Parse name-addr part of the header */
		if (parse_nameaddr(&s, &r->nameaddr) < 0) {
			LOG(L_ERR, "parse_rr(): Error while parsing name-addr (%.*s)\n",
					s.len, ZSW(s.s));
			goto error;
		}
		r->len = r->nameaddr.len;

		     /* Shift just behind the closing > */
		s.s = r->nameaddr.name.s + r->nameaddr.len;  /* Point just behind > */
		s.len -= r->nameaddr.len;

		trim_leading(&s); /* Skip any white-chars */

		if (s.len == 0) goto ok; /* Nothing left, finish */
		
		if (s.s[0] == ';') {         /* Route parameter found */
			s.s++;
			s.len--;
			trim_leading(&s);
			
			if (s.len == 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}

			     /* Parse all parameters */
			if (parse_params(&s, CLASS_ANY, &hooks, &r->params) < 0) {
				LOG(L_ERR, "parse_rr(): Error while parsing params\n");
				goto error;
			}
			r->len = r->params->name.s + r->params->len - r->nameaddr.name.s;

			     /* Copy hooks */
			     /*r->r2 = hooks.rr.r2; */

			trim_leading(&s);
			if (s.len == 0) goto ok;
		}

		if (s.s[0] != ',') {
			LOG(L_ERR, "parse_rr(): Invalid character '%c', comma expected\n", s.s[0]);
			goto error;
		}
		
		     /* Next character is comma or end of header*/
		s.s++;
		s.len--;
		trim_leading(&s);

		if (s.len == 0) {
			LOG(L_ERR, "parse_rr(): Text after comma missing\n");
			goto error;
		}

		     /* Append the structure as last parameter of the linked list */
		if (!*head) *head = r;
		if (last) last->next = r;
		last = r;
	}

 error:
	if (r) free_rr(&r);
	free_rr(head); /* Free any contacts created so far */
	return -1;

 ok:
	if (!*head) *head = r;
	if (last) last->next = r;
	return 0;
}
/*
 * Parse parameters
 * _s is string containing parameters, it will be updated to point behind the parameters
 * _c is class of parameters
 * _h is pointer to structure that will be filled with pointer to well known parameters
 * linked list of parsed parameters will be stored in
 * the variable _p is pointing to
 * The function returns 0 on success and negative number
 * on an error
 */
int parse_params(str* _s, pclass_t _c, param_hooks_t* _h, param_t** _p)
{
	param_t* t;

	if (!_s || !_h || !_p) {
		LOG(L_ERR, "parse_params(): Invalid parameter value\n");
		return -1;
	}

	memset(_h, 0, sizeof(param_hooks_t));
	*_p = 0;

	if (!_s->s) { /* no parameters at all -- we're done */
		DBG("DEBUG: parse_params: empty uri params, skipping\n");
		return 0;
	}
			
	while(1) {
		t = (param_t*)pkg_malloc(sizeof(param_t));
		if (t == 0) {
			LOG(L_ERR, "parse_params(): No memory left\n");
			goto error;
		}
		memset(t, 0, sizeof(param_t));

		parse_param_name(_s, _c, _h, t);
		trim_leading(_s);
		
		if (_s->len == 0) { /* The last parameter without body */
			goto ok;
		}
		
		if (_s->s[0] == '=') {
			_s->s++;
			_s->len--;
			trim_leading(_s);

			if (_s->len == 0) {
				LOG(L_ERR, "parse_params(): Body missing\n");
				goto error;
			}

			if (parse_param_body(_s, t) < 0) {
				LOG(L_ERR, "parse_params(): Error while parsing param body\n");
				goto error;
			}

			t->len = _s->s - t->name.s;

			trim_leading(_s);
			if (_s->len == 0) {
				goto ok;
			}
		} else {
			t->len = _s->s - t->name.s;
		}

		if (_s->s[0] == ',') goto ok; /* To be able to parse header parameters */
		if (_s->s[0] == '>') goto ok; /* To be able to parse URI parameters */

		if (_s->s[0] != ';') {
			LOG(L_ERR, "parse_params(): Invalid character, ; expected\n");
			goto error;
		}

		_s->s++;
		_s->len--;
		trim_leading(_s);
		
		if (_s->len == 0) {
			LOG(L_ERR, "parse_params(): Param name missing after ;\n");
			goto error;
		}

		t->next = *_p;
		*_p = t;
	}

 error:
	if (t) pkg_free(t);
	free_params(*_p);
	return -2;

 ok:
	t->next = *_p;
	*_p = t;
	return 0;
}
Exemple #24
0
static int attr_hdr_body2attrs(struct sip_msg* m, char* header_, char* prefix_)
{
    char name_buf[50];
    str *prefix = (str*) prefix_;
    struct hdr_name *header = (void*) header_;
    struct hdr_field *hf;
    str s, name, val;
    int_str name2, val2;
    int val_type, arr;
    if (header->kind == HDR_STR) {
	if (parse_headers(m, HDR_EOH_F, 0) == -1) {
	    LOG(L_ERR, "ERROR: attr_hdr_body2attrs: Error while parsing message\n");
	    return -1;
	}
	
	for (hf=m->headers; hf; hf=hf->next) {
	    if ( (header->name.s.len == hf->name.len)
		 && (!strncasecmp(header->name.s.s, hf->name.s, hf->name.len)) ) {
		break;
	    }
	}
    }
    else {
	if (parse_headers(m, header->name.n, 0) == -1) {
	    LOG(L_ERR, "ERROR: attr_hdr_body2attrs: Error while parsing message\n");
	    return -1;
	}
	switch (header->name.n) {
		 //	HDR_xxx:
	default:
	    hf = NULL;
	    break;
	}
    }
    if (!hf || !hf->body.len)
	return 1;
    
	 // parse body of hf
    s = hf->body;
    name_buf[0] = '\0';
    while (s.len) {
	trim_leading(&s);
	name.s = s.s;
	while ( s.len &&
		( (s.s[0] >= 'a' && s.s[0] <= 'z') ||
		  (s.s[0] >= 'A' && s.s[0] <= 'Z') ||
		  (s.s[0] >= '0' && s.s[0] <= '9') ||
		  s.s[0] == '_' || s.s[0] == '-'
		  ) ) {
	    s.s++;
	    s.len--;
	}
	if (s.s == name.s)
	    break;
	name.len = s.s - name.s;
	trim_leading(&s);
	if (!s.len)
	    break;
	if (s.s[0] == '=') {
	    s.s++;
	    s.len--;
	    arr = -1;
	    
	    while (s.len) {
		trim_leading(&s);
		val_type = 0;
		if (!s.len)
		    break;
		if (s.s[0] == '"') {
		    s.s++;
		    s.len--;
		    val.s = s.s;
		    
		    s.s = q_memchr(s.s, '\"', s.len);
		    if (!s.s)
			break;
		    val.len = s.s - val.s;
		    val_type = AVP_VAL_STR;
		    s.s++;
		    s.len -= s.s - val.s;
		}
		else {
		    int r;
		    val.s = s.s;
		    if (s.s[0] == '+' || s.s[0] == '-') {
			s.s++;
			s.len--;
		    }
		    val2.n = 0; r = 0;
		    while (s.len) {
			if (s.s[0] == header->field_delimiter || (header->array_delimiter && header->array_delimiter == s.s[0]))
			    goto token_end;
			switch (s.s[0]) {
			case ' ':
			case '\t':
			case '\n':
			case '\r':
			    goto token_end;
			}
			if (!val_type && s.s[0] >= '0' && s.s[0]<= '9') {
			    r++;
			    val2.n *= 10;
			    val2.n += s.s[0] - '0';
				 // overflow detection ???
			}
			else {
			    val_type = AVP_VAL_STR;
			}
			s.s++;
			s.len--;
		    }
		token_end:
		    if (r == 0) val_type = AVP_VAL_STR;
		    if (!val_type && val.s[0] == '-') {
			val2.n = -val2.n;
		    }
		    val.len = s.s - val.s;
		}
		trim_leading(&s);
		if (arr >= 0 || (s.len && header->array_delimiter && header->array_delimiter == s.s[0])) {
		    arr++;
		    if (arr == 100)
			LOG(L_ERR, "ERROR: avp index out of limit\n");
		}
		if (val.len && arr < 100) {
		    if (prefix != NULL || arr >= 0) {
			if ((prefix?prefix->len:0)+name.len+1+((arr>=0)?3/*#99*/:0) > sizeof(name_buf)) {
			    if (arr <= 0)
				LOG(L_ERR, "ERROR: avp name too long\n");
			    goto cont;
			}
			name2.s.len = 0;
			name2.s.s = name_buf;
			if (prefix != NULL) {
			    if (name_buf[0] == '\0') {
				memcpy(&name_buf[0], prefix->s, prefix->len);
			    }
			    name2.s.len += prefix->len;
			}
			if (arr <= 0) {
			    memcpy(&name_buf[name2.s.len], name.s, name.len);
			}
			name2.s.len += name.len;
			if (arr >= 0) {
			    name_buf[name2.s.len] = '#';
			    name2.s.len++;
			    if (arr >= 10) {
				name_buf[name2.s.len] = '0'+ (arr / 10);
				name2.s.len++;
			    }
			    name_buf[name2.s.len] = '0'+ (arr % 10);
			    name2.s.len++;
			}
		    }
		    else {
			name2.s.s = name.s;
			name2.s.len = name.len;
		    }
		    if ( ((val_type & AVP_VAL_STR) && (header->val_types & VAL_TYPE_STR)) ||
			 ((val_type & AVP_VAL_STR) == 0 && (header->val_types & VAL_TYPE_INT))  ) {
			if (val_type) {
			    val2.s.s = val.s;
			    val2.s.len = val.len;
			    DBG("DEBUG: attr_hdr_body2attrs: adding avp '%.*s', sval: '%.*s'\n", name2.s.len, (char*) name2.s.s, val.len, val.s);
			} else {
			    DBG("DEBUG: attr_hdr_body2attrs: adding avp '%.*s', ival: '%d'\n", name2.s.len, (char*) name2.s.s, val2.n);
			}
			if ( add_avp(AVP_NAME_STR | val_type, name2, val2)!=0) {
			    LOG(L_ERR, "ERROR: attr_hdr_body2attrs: add_avp failed\n");
			    return 1;
			}
		    }
		}
	    cont:
		if (s.len && header->array_delimiter && header->array_delimiter == s.s[0]) {
		    s.s++;
		    s.len--;
		}
		else {
		    break;
		}
	    };
	}
	if (s.len && s.s[0] == header->field_delimiter) {
	    s.s++;
	    s.len--;
	}
	else {
	    break;
	}
    }
    return 1;
}
Exemple #25
0
/*!  \brief
 * Only parse one parameter
 * Returns:
 * 	t: out parameter
 * 	-1: on error
 * 	0: success, but expect a next paramter
 * 	1: success and expect no more parameters
 */
static inline int parse_param2(
		str *_s, pclass_t _c, param_hooks_t *_h, param_t *t, char separator)
{
	memset(t, 0, sizeof(param_t));

	parse_param_name(_s, _c, _h, t, separator);
	trim_leading(_s);

	if(_s->len == 0) { /* The last parameter without body */
		t->len = t->name.len;
		goto ok;
	}

	if(_s->s[0] == '=') {
		_s->s++;
		_s->len--;
		trim_leading(_s);

		if(_s->len == 0) {
			/* Be forgiving and accept parameters with missing value,
			 * we just set the length of parameter body to 0. */
			t->body.s = _s->s;
			t->body.len = 0;
		} else if(parse_param_body(_s, t, separator) < 0) {
			LM_ERR("Error while parsing param body\n");
			goto error;
		}

		t->len = _s->s - t->name.s;

		trim_leading(_s);
		if(_s->len == 0) {
			goto ok;
		}
	} else {
		t->len = t->name.len;
	}

	if(_s->s[0] == ',')
		goto ok; /* To be able to parse header parameters */
	if(_s->s[0] == '>')
		goto ok; /* To be able to parse URI parameters */

	if(_s->s[0] != separator) {
		LM_ERR("Invalid character, %c expected\n", separator);
		goto error;
	}

	_s->s++;
	_s->len--;
	trim_leading(_s);

	if(_s->len == 0) {
		LM_ERR("Param name missing after %c\n", separator);
		goto error;
	}

	return 0; /* expect more params */

ok:
	return 1; /* done with parsing for params */
error:
	return -1;
}
Exemple #26
0
/*!
 * This method is used to parse Privacy HF body, which consist of
 * comma separated list of priv-values.  After parsing, msg->privacy->parsed
 * contains enum bits of privacy values defined in parse_privacy.h.
 * \return 0 on success and -1 on failure.
 */
int parse_privacy(struct sip_msg *msg)
{
    unsigned int val_len, value, values, len;
    str next;
    char *p, *beyond;

    /* maybe the header is already parsed! */
    if (msg->privacy && msg->privacy->parsed)
        return 0;

    /* parse Privacy HF (there should be only one) */
    if (!msg->privacy &&
            (parse_headers(msg, HDR_PRIVACY_F, 0) == -1 || !msg->privacy)) {
        return -1;
    }

    next.len = msg->privacy->body.len;
    next.s = msg->privacy->body.s;

    trim_leading(&next);

    if (next.len == 0) {
        LM_ERR("no values\n");
        return -1;
    }

    values = 0;
    p = next.s;
    len = next.len;
    beyond = p + len;

    while (p < beyond) {
        if((val_len = parse_priv_value(p, len, &value)) != 0) {
            values |= value;
            p = p + val_len;
            len = len - val_len;
        } else {
            LM_ERR("invalid privacy value\n");
            return -1;
        }

        while(p < beyond && (*p == ' ' || *p == '\t'
                             || *p == '\r' || *p == '\n'))
            p++;

        if(p >= beyond) break;

        if (*p == ';') {
            p++;
            while(p < beyond && (*p == ' ' || *p == '\t'
                                 || *p == '\r' || *p == '\n'))
                p++;
            if(p >= beyond) {
                LM_ERR("no privacy value after comma\n");
                return -1;
            }
        } else {
            LM_ERR("semicolon expected\n");
            return -1;
        }
    }

    if ((values & PRIVACY_NONE) && (values ^ PRIVACY_NONE)) {
        LM_ERR("no other privacy values allowed with 'none'\n");
        return -1;
    }

    msg->privacy->parsed = (void *)(long)values;

    return 0;
}
Exemple #27
0
int seek_config_path(FILE *f, char *config_path) {
    /*
     * Assumes the file pointer f points at the start of a rapified
     * class body. The config path should be formatted like one used
     * by the ingame commands (case insensitive):
     *
     *   CfgExample >> MyClass >> MyValue
     *
     * This function then moves the file pointer to the start of the
     * desired class entry (or class body for classes).
     *
     * Returns a positive integer on failure, a 0 on success and -1
     * if the given path doesn't exist.
     */

    int i;
    uint8_t type;
    uint32_t num_entries;
    uint32_t fp;
    char path[2048];
    char target[512];
    char buffer[512];

    // Trim leading spaces
    strncpy(path, config_path, sizeof(path));
    trim_leading(path, sizeof(path));

    // Extract first element
    for (i = 0; i < sizeof(target) - 1; i++) {
        if (path[i] == 0 || path[i] == '>' || path[i] == ' ')
            break;
    }
    strncpy(target, path, i);
    target[i] = 0;

    // Inherited classname
    while (fgetc(f) != 0);

    num_entries = read_compressed_int(f);

    for (i = 0; i < num_entries; i++) {
        fp = ftell(f);
        type = fgetc(f);

        if (type == 0) { // class
            if (fgets(buffer, sizeof(buffer), f) == NULL)
                return 1;

            fseek(f, fp + strlen(buffer) + 2, SEEK_SET);
            fread(&fp, 4, 1, f);

            if (stricmp(buffer, target))
                continue;

            fseek(f, fp, SEEK_SET);

            if (strchr(path, '>') == NULL)
                return 0;

            strcpy(path, strchr(config_path, '>') + 2);
            return seek_config_path(f, path);
        } else if (type == 1) { // value
            type = fgetc(f);

            if (fgets(buffer, sizeof(buffer), f) == NULL)
                return 1;

            if (stricmp(buffer, target) == 0) {
                fseek(f, fp, SEEK_SET);
                return 0;
            }

            fseek(f, fp + strlen(buffer) + 3, SEEK_SET);

            if (type == 0)
                while (fgetc(f) != 0);
            else
                fseek(f, 4, SEEK_CUR);
        } else if (type == 2) { // array
            if (fgets(buffer, sizeof(buffer), f) == NULL)
                return 1;

            if (stricmp(buffer, target) == 0) {
                fseek(f, fp, SEEK_SET);
                return 0;
            }

            fseek(f, fp + strlen(buffer) + 2, SEEK_SET);

            skip_array(f);
        } else { // extern & delete statements
            while (fgetc(f) != 0);
        }
    }

    return -1;
}
Exemple #28
0
int preprocess(char *source, FILE *f_target, struct constant *constants) {
    /*
     * Writes the contents of source into the target file pointer, while
     * recursively resolving constants and includes using the includefolder
     * for finding included files.
     *
     * Returns 0 on success, a positive integer on failure.
     */

    extern int current_operation;
    extern char current_target[2048];
    extern char include_stack[MAXINCLUDES][1024];
    int line = 0;
    int i = 0;
    int j = 0;
    int level = 0;
    int level_true = 0;
    int level_comment = 0;
    int success;
    size_t buffsize;
    char *buffer;
    char *ptr;
    char *token;
    char in_string = 0;
    char valuebuffer[262144];
    char definition[256];
    char tmp[2048];
    char includepath[2048];
    char actualpath[2048];
    FILE *f_source;

    current_operation = OP_PREPROCESS;
    strcpy(current_target, source);

    for (i = 0; i < MAXINCLUDES && include_stack[i][0] != 0; i++) {
        if (strcmp(source, include_stack[i]) == 0) {
            errorf("Circular dependency detected, printing include stack:\n", source);
            fprintf(stderr, "    !!! %s\n", source);
            for (j = MAXINCLUDES - 1; j >= 0; j--) {
                if (include_stack[j][0] == 0)
                    continue;
                fprintf(stderr, "        %s\n", include_stack[j]);
            }
            return 1;
        }
    }

    if (i == MAXINCLUDES) {
        errorf("Too many nested includes.\n");
        return 1;
    }

    strcpy(include_stack[i], source);

    f_source = fopen(source, "rb");
    if (!f_source) {
        errorf("Failed to open %s.\n", source);
        return 1;
    }

    // Skip byte order mark if it exists
    if (fgetc(f_source) == 0xef)
        fseek(f_source, 3, SEEK_SET);
    else
        fseek(f_source, 0, SEEK_SET);

    // first constant is file name
    // @todo: what form?
    strcpy(constants[0].name, "__FILE__");
    if (constants[0].value == 0)
        constants[0].value = (char *)malloc(1024);
    snprintf(constants[0].value, 1024, "\"%s\"", source);

    strcpy(constants[1].name, "__LINE__");

    strcpy(constants[2].name, "__EXEC");
    if (constants[2].value == 0)
        constants[2].value = (char *)malloc(1);

    strcpy(constants[3].name, "__EVAL");
    if (constants[3].value == 0)
        constants[3].value = (char *)malloc(1);

    while (true) {
        // get line
        line++;
        buffsize = LINEBUFFSIZE;
        buffer = (char *)malloc(buffsize + 1);
        if (getline(&buffer, &buffsize, f_source) == -1) {
            free(buffer);
            break;
        }

        // fix Windows line endings
        if (strlen(buffer) >= 2 && buffer[strlen(buffer) - 2] == '\r') {
            buffer[strlen(buffer) - 2] = '\n';
            buffer[strlen(buffer) - 1] = 0;
        }

        // add next lines if line ends with a backslash
        while (strlen(buffer) >= 2 && buffer[strlen(buffer) - 2] == '\\') {
            if (strlen(buffer) >= buffsize) {
                errorf("Line %i exceeds maximum length.\n", line);
                return 1;
            }
            buffsize -= strlen(buffer);
            ptr = (char *)malloc(buffsize + 1);
            if (getline(&ptr, &buffsize, f_source) == -1)
                break;
            strncpy(strrchr(buffer, '\\'), ptr, buffsize);
            line++;
            free(ptr);

            // fix windows line endings again
            if (strlen(buffer) >= 2 && buffer[strlen(buffer) - 2] == '\r') {
                buffer[strlen(buffer) - 2] = '\n';
                buffer[strlen(buffer) - 1] = 0;
            }
        }

        // Check for block comment delimiters
        for (i = 0; i < strlen(buffer); i++) {
            if (in_string != 0) {
                if (buffer[i] == in_string && buffer[i-1] != '\\')
                    in_string = 0;
                else
                    continue;
            } else {
                if (level_comment == 0 &&
                        (buffer[i] == '"' || buffer[i] == '\'') &&
                        (i == 0 || buffer[i-1] != '\\'))
                    in_string = buffer[i];
            }

            if (buffer[i] == '/' && buffer[i+1] == '/') {
                buffer[i+1] = 0;
                buffer[i] = '\n';
            } else if (buffer[i] == '/' && buffer[i+1] == '*') {
                level_comment++;
                buffer[i] = ' ';
                buffer[i+1] = ' ';
            } else if (buffer[i] == '*' && buffer[i+1] == '/') {
                level_comment--;
                if (level_comment < 0)
                    level_comment = 0;
                buffer[i] = ' ';
                buffer[i+1] = ' ';
            }

            if (level_comment > 0) {
                buffer[i] = ' ';
                continue;
            }
        }

        // trim leading spaces
        trim_leading(buffer, LINEBUFFSIZE);

        // skip lines inside untrue ifs
        if (level > level_true) {
            if ((strlen(buffer) < 5 || strncmp(buffer, "#else", 5) != 0) &&
                    (strlen(buffer) < 6 || strncmp(buffer, "#endif", 6) != 0)) {
                free(buffer);
                continue;
            }
        }

        // second constant is line number
        if (constants[1].value == 0)
            constants[1].value = (char *)malloc(16);
        sprintf(constants[1].value, "%i", line - 1);

        // get the constant name
        if (strlen(buffer) >= 9 && (strncmp(buffer, "#define", 7) == 0 ||
                strncmp(buffer, "#undef", 6) == 0 ||
                strncmp(buffer, "#ifdef", 6) == 0 ||
                strncmp(buffer, "#ifndef", 7) == 0)) {
            definition[0] = 0;
            ptr = buffer + 7;
            while (*ptr == ' ')
                ptr++;
            strncpy(definition, ptr, 256);
            ptr = definition;
            while (*ptr != ' ' && *ptr != '(' && *ptr != '\n')
                ptr++;
            *ptr = 0;

            if (strlen(definition) == 0) {
                errorf("Missing definition in line %i of %s.\n", line, source);
                return 2;
            }
        }

        // check for preprocessor commands
        if (level_comment == 0 && strlen(buffer) >= 9 && strncmp(buffer, "#define", 7) == 0) {
            i = 0;
            while (strlen(constants[i].name) != 0 &&
                    strcmp(constants[i].name, definition) != 0 &&
                    i <= MAXCONSTS)
                i++;

            if (i == MAXCONSTS) {
                errorf("Maximum number of %i definitions exceeded in line %i of %s.\n", MAXCONSTS, line, source);
                return 3;
            }

            if (constants[i].name[0] != 0)
                nwarningf("redefinition-wo-undef", "Constant \"%s\" is being redefined without an #undef in line %i.\n", definition, line);

            ptr = buffer + strlen(definition) + 8;
            while (*ptr != ' ' && *ptr != '\t' && *ptr != '(' && *ptr != '\n')
                ptr++;

            // Get arguments and resolve macros in macro
            for (j = 0; j < MAXARGS; j++)
                constants[i].arguments[j][0] = 0;

            if (*ptr == '(' && strchr(ptr, ')') != NULL) {
                strncpy(tmp, ptr + 1, sizeof(tmp));

                if (strchr(tmp, ')') == NULL) {
                    errorf("Macro arguments too long in line %i of %s.\n", line, source);
                }
                *strchr(tmp, ')') = 0;

                token = strtok(tmp, ",");
                for (j = 0; j < MAXARGS && token; j++) {
                    strncpy(constants[i].arguments[j], token, sizeof(constants[i].arguments[j]));
                    trim(constants[i].arguments[j], sizeof(constants[i].arguments[j]));

                    token = strtok(NULL, ",");
                }

                ptr = strchr(ptr, ')') + 1;
            }

            while (*ptr == ' ' || *ptr == '\t')
                ptr++;

            if (*ptr != '\n') {
                strncpy(valuebuffer, ptr, sizeof(valuebuffer));
                valuebuffer[strlen(valuebuffer) - 1] = 0;

                success = resolve_macros(valuebuffer, sizeof(valuebuffer), constants);
                if (success) {
                    errorf("Failed to resolve macros in line %i of %s.\n", line, source);
                    return success;
                }

                if (strnlen(valuebuffer, sizeof(valuebuffer)) == sizeof(valuebuffer)) {
                    errorf("Macro value in line %i of %s exceeds maximum size (%i).\n", line, source, sizeof(valuebuffer));
                    return 3;
                }

                if (constants[i].value != 0)
                    free(constants[i].value);
                constants[i].value = (char *)malloc(strlen(valuebuffer) + 1);
                strcpy(constants[i].value, valuebuffer);
            } else {
                constants[i].value = (char *)malloc(1);
                constants[i].value[0] = 0;
            }

            strncpy(constants[i].name, definition, sizeof(constants[i].name));
        } else if (level_comment == 0 && strlen(buffer) >= 6 && strncmp(buffer, "#undef", 6) == 0) {
            i = 0;
            while (strlen(constants[i].name) != 0 &&
                    strcmp(constants[i].name, definition) != 0 &&
                    i <= MAXCONSTS)
                i++;

            if (i == MAXCONSTS) {
                errorf("Include %s not found in line %i of %s.\n", definition, line, source);
                return 3;
            }

            constants[i].name[0] = 0;
        } else if (level_comment == 0 && strlen(buffer) >= 8 &&
                (strncmp(buffer, "#ifdef", 6) == 0 || strncmp(buffer, "#ifndef", 7) == 0)) {
            level++;
            if (strncmp(buffer, "#ifndef", 7) == 0)
                level_true++;
            for (i = 0; i < MAXCONSTS; i++) {
                if (strcmp(definition, constants[i].name) == 0) {
                    if (strncmp(buffer, "#ifdef", 6) == 0)
                        level_true++;
                    if (strncmp(buffer, "#ifndef", 7) == 0)
                        level_true--;
                }
            }
        } else if (level_comment == 0 && strlen(buffer) >= 5 && strncmp(buffer, "#else", 5) == 0) {
            if (level == level_true)
                level_true--;
            else
                level_true = level;
        } else if (level_comment == 0 && strlen(buffer) >= 6 && strncmp(buffer, "#endif", 6) == 0) {
            if (level == 0) {
                errorf("Unexpected #endif in line %i of %s.\n", line, source);
                return 4;
            }
            if (level == level_true)
                level_true--;
            level--;
        } else if (level_comment == 0 && strlen(buffer) >= 11 && strncmp(buffer, "#include", 8) == 0) {
            for (i = 0; i < strlen(buffer) ; i++) {
                if (buffer[i] == '<' || buffer[i] == '>')
                    buffer[i] = '"';
            }
            if (strchr(buffer, '"') == NULL) {
                errorf("Failed to parse #include in line %i in %s.\n", line, source);
                return 5;
            }
            strncpy(includepath, strchr(buffer, '"') + 1, sizeof(includepath));
            if (strchr(includepath, '"') == NULL) {
                errorf("Failed to parse #include in line %i in %s.\n", line, source);
                return 6;
            }
            *strchr(includepath, '"') = 0;
            if (find_file(includepath, source, actualpath)) {
                errorf("Failed to find %s.\n", includepath);
                return 7;
            }
            free(buffer);
            success = preprocess(actualpath, f_target, constants);
            if (success)
                return success;

            current_operation = OP_PREPROCESS;
            strcpy(current_target, source);

            for (i = 0; i < MAXINCLUDES && include_stack[i][0] != 0; i++);
            include_stack[i - 1][0] = 0;

            continue;
        }

        if (buffer[0] != '#' && strlen(buffer) > 1) {
            success = resolve_macros(buffer, buffsize, constants);
            if (success) {
                errorf("Failed to resolve macros in line %i of %s.\n", line, source);
                return success;
            }
            fputs(buffer, f_target);
        }
        free(buffer);
    }

    fclose(f_source);

    return 0;
}
Exemple #29
0
/*
 * Parse parameters
 * _s is string containing parameters, it will be updated to point behind the parameters
 * _c is class of parameters
 * _h is pointer to structure that will be filled with pointer to well known parameters
 * linked list of parsed parameters will be stored in
 * the variable _p is pointing to
 * The function returns 0 on success and negative number
 * on an error
 */
int parse_params(str* _s, pclass_t _c, param_hooks_t* _h, param_t** _p)
{
	param_t* t;
	param_t* last;

	if (!_s || !_h || !_p) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	memset(_h, 0, sizeof(param_hooks_t));
	last = NULL;
	*_p = 0;

	if (!_s->s) { /* no parameters at all -- we're done */
		LM_DBG("empty uri params, skipping\n");
		return 0;
	}

	LM_DBG("Parsing params for:[%.*s]\n",_s->len,_s->s);

	while(1) {
		t = (param_t*)pkg_malloc(sizeof(param_t));
		if (t == 0) {
			LM_ERR("no pkg memory left\n");
			goto error;
		}
		memset(t, 0, sizeof(param_t));

		parse_param_name(_s, _c, _h, t);
		trim_leading(_s);
		
		if (_s->len == 0) { /* The last parameter without body */
			t->len = t->name.len;
			goto ok;
		}
		
		if (_s->s[0] == '=') {
			_s->s++;
			_s->len--;
			trim_leading(_s);

			if (_s->len == 0) {
				LM_ERR("body missing\n");
				goto error;
			}

			if (parse_param_body(_s, t) < 0) {
				LM_ERR("failed to parse param body\n");
				goto error;
			}

			t->len = _s->s - t->name.s;

			trim_leading(_s);
			if (_s->len == 0) {
				goto ok;
			}
		} else {
			t->len = t->name.len;
		}

		if (_s->s[0]==',') goto ok; /* To be able to parse header parameters */
		if (_s->s[0]=='>') goto ok; /* To be able to parse URI parameters */

		if (_s->s[0] != ';') {
			LM_ERR("invalid character, ; expected, found %c \n",_s->s[0]);
			goto error;
		}

		_s->s++;
		_s->len--;
		trim_leading(_s);
		
		if (_s->len == 0) {
			LM_ERR("param name missing after ;\n");
			goto error;
		}

		if (last) {last->next=t;} else {*_p = t;}
		last = t;
	}

error:
	if (t) pkg_free(t);
	free_params(*_p);
	*_p = 0;
	return -2;

ok:
	if (last) {last->next=t;} else {*_p = t;}
	_h->last_param = last = t;
	return 0;
}
/**
 * Only parse one parameter
 * Returns:
 * 	t: out parameter
 * 	-1: on error
 * 	0: success, but expect a next paramter
 * 	1: success and exepect no more parameters
 */
inline int parse_param(str *_s, pclass_t _c, param_hooks_t *_h, param_t *t)
{
	memset(t, 0, sizeof(param_t));

	parse_param_name(_s, _c, _h, t);
	trim_leading(_s);
	
	if (_s->len == 0) { /* The last parameter without body */
		t->len = t->name.len;
		goto ok;
	}
	
	if (_s->s[0] == '=') {
		_s->s++;
		_s->len--;
		trim_leading(_s);

		if (_s->len == 0) {
			LOG(L_ERR, "parse_params(): Body missing\n");
			goto error;
		}

		if (parse_param_body(_s, t) < 0) {
			LOG(L_ERR, "parse_params(): Error while parsing param body\n");
			goto error;
		}

		t->len = _s->s - t->name.s;

		trim_leading(_s);
		if (_s->len == 0) {
			goto ok;
		}
	} else {
		t->len = t->name.len;
	}

	if (_s->s[0] == ',') goto ok; /* To be able to parse header parameters */
	if (_s->s[0] == '>') goto ok; /* To be able to parse URI parameters */

	if (_s->s[0] != ';') {
		LOG(L_ERR, "parse_params(): Invalid character, ; expected\n");
		goto error;
	}

	_s->s++;
	_s->len--;
	trim_leading(_s);
	
	if (_s->len == 0) {
		LOG(L_ERR, "parse_params(): Param name missing after ;\n");
		goto error;
	}

	return 0; /* expect more params */

ok:
	return 1; /* done with parsing for params */
error:
	return -1;
}