Beispiel #1
0
static void httpd_handler(const struct pl *uri, struct mbuf *mb)
{
	struct pl cmd, params, r;
	uint32_t refresh = 0;

	if (re_regex(uri->p, uri->l, "/[^?]*[^]*", &cmd, &params))
		return;

	if (!re_regex(params.p, params.l, "[?&]1r=[0-9]+", NULL, &r))
		refresh = pl_u32(&r);

	mbuf_write_str(mb, "<html>\n<head>\n");
	mbuf_write_str(mb, " <title>Restund Server Status</title>\n");

	if (refresh)
		mbuf_printf(mb,
			    " <meta http-equiv=\"refresh\" content=\"%u\">\n",
			    refresh);

	mbuf_write_str(mb, "</head>\n<body>\n");
	mbuf_write_str(mb, "<h2>Restund Server Status</h2>\n");
	server_info(mb);
	mbuf_write_str(mb, "<hr size=\"1\"/>\n<pre>\n");
	restund_cmd(&cmd, mb);
	mbuf_write_str(mb, "</pre>\n</body>\n</html>\n");
}
Beispiel #2
0
static int parse_resolv_conf(char *domain, size_t dsize,
			     struct sa *srvv, uint32_t *n)
{
	FILE *f;
	struct pl dom = pl_null;
	uint32_t i = 0;
	int err = 0;

	if (!srvv || !n || !*n)
		return EINVAL;

	f = fopen("/etc/resolv.conf", "r");
	if (!f)
		return errno;

	for (;;) {
		char line[128];
		struct pl srv;
		size_t len;

		if (1 != fscanf(f, "%127[^\n]\n", line))
			break;

		if ('#' == line[0])
			continue;

		len = str_len(line);

		/* Set domain if not already set */
		if (!pl_isset(&dom)) {
			if (0 == re_regex(line, len, "domain [^ ]+", &dom)) {
				(void)pl_strcpy(&dom, domain, dsize);
			}

			if (0 == re_regex(line, len, "search [^ ]+", &dom)) {
				(void)pl_strcpy(&dom, domain, dsize);
			}
		}

		/* Use the first entry */
		if (i < *n && 0 == re_regex(line, len, "nameserver [^\n]+",
					    &srv)) {
			err = sa_set(&srvv[i], &srv, DNS_PORT);
			if (err) {
				DEBUG_WARNING("sa_set: %r (%m)\n", &srv, err);
			}
			++i;
		}
	}

	*n = i;

	(void)fclose(f);

	return err;
}
Beispiel #3
0
static void notify_handler(struct sip *sip, const struct sip_msg *msg,
			   void *arg)
{
	enum presence_status status = PRESENCE_CLOSED;
	struct presence *pres = arg;
	const struct sip_hdr *hdr;
	struct pl pl;

	pres->failc = 0;

	hdr = sip_msg_hdr(msg, SIP_HDR_CONTENT_TYPE);
	if (!hdr || 0 != pl_strcasecmp(&hdr->val, "application/pidf+xml")) {

		if (hdr)
			(void)re_printf("presence: unsupported"
					" content-type: '%r'\n",
					&hdr->val);

		sip_treplyf(NULL, NULL, sip, msg, false,
			    415, "Unsupported Media Type",
			    "Accept: application/pidf+xml\r\n"
			    "Content-Length: 0\r\n"
			    "\r\n");
		return;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<status>[^<]*<basic>[^<]*</basic>[^<]*</status>",
		      NULL, &pl, NULL)) {

		if (!pl_strcasecmp(&pl, "open"))
			status = PRESENCE_OPEN;
	}

	if (!re_regex((const char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		      "<rpid:away/>")) {

		status = PRESENCE_CLOSED;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:busy/>")) {

		status = PRESENCE_BUSY;
	}
	else if (!re_regex((const char *)mbuf_buf(msg->mb),
			   mbuf_get_left(msg->mb),
			   "<rpid:on-the-phone/>")) {

		status = PRESENCE_BUSY;
	}

	(void)sip_treply(NULL, sip, msg, 200, "OK");

	contact_set_presence(pres->contact, status);
}
Beispiel #4
0
static int decode_hostport(const struct pl *hostport, struct pl *host,
                           struct pl *port)
{
    /* Try IPv6 first */
    if (!re_regex(hostport->p, hostport->l, "\\[[0-9a-f:]+\\][:]*[0-9]*",
                  host, NULL, port))
        return 0;

    /* Then non-IPv6 host */
    return re_regex(hostport->p, hostport->l, "[^:]+[:]*[0-9]*",
                    host, NULL, port);
}
Beispiel #5
0
static int media_decode(struct sdp_media **mp, struct sdp_session *sess,
			bool offer, const struct pl *pl)
{
	struct pl name, port, proto, fmtv, fmt;
	struct sdp_media *m;
	int err;

	if (re_regex(pl->p, pl->l, "[a-z]+ [^ ]+ [^ ]+[^]*",
		     &name, &port, &proto, &fmtv))
		return EBADMSG;

	m = list_ledata(*mp ? (*mp)->le.next : sess->medial.head);
	if (!m) {
		if (!offer)
			return EPROTO;

		m = sdp_media_find(sess, &name, &proto);
		if (!m) {
			err = sdp_media_radd(&m, sess, &name, &proto);
			if (err)
				return err;
		}
		else {
			list_unlink(&m->le);
			list_append(&sess->medial, &m->le, m);
		}
	}
	else {
		if (pl_strcmp(&name, m->name))
			return offer ? ENOTSUP : EPROTO;

		if (pl_strcmp(&proto, m->proto))
			return ENOTSUP;
	}

	while (!re_regex(fmtv.p, fmtv.l, " [^ ]+", &fmt)) {

		pl_advance(&fmtv, fmt.p + fmt.l - fmtv.p);

		err = sdp_format_radd(m, &fmt);
		if (err)
			return err;
	}

	m->raddr = sess->raddr;
	sa_set_port(&m->raddr, pl_u32(&port));

	m->rdir = sess->rdir;

	*mp = m;

	return 0;
}
Beispiel #6
0
/** Compare two SDP messages line-by-line (exclude owner) */
static bool sdp_cmp(struct mbuf *mb, const char *msg)
{
	struct pl pl;

	if (!mb || !msg)
		return false;

	pl.p = (char *)mb->buf;
	pl.l = mb->end;

	while (pl.l && strlen(msg)) {
		struct pl n1, v1, n2, v2;

		if (re_regex(pl.p, pl.l,
			     "[^=]1=[^\r\n]+", &n1, &v1))
			return false;

		if (re_regex(msg, strlen(msg),
			     "[^=]1=[^\r\n]+", &n2, &v2))
			return false;

		pl_advance(&pl, 2 + v1.l + 2);
		msg += (2 + v2.l + 2);

		if (0 != pl_cmp(&n1, &n2)) {
			DEBUG_WARNING("name mismatch: %r=%r\n", &n1, &v1);
			return false;
		}

		/* ignore owner */
		if (n1.p[0] == 'o')
			continue;

		if (0 != pl_cmp(&v1, &v2)) {
			DEBUG_WARNING("value mismatch: %r=%r\n",
				      &n1, &v1);
			return false;
		}
	}

	if (pl.l) {
		DEBUG_WARNING("%u bytes junk at end: %r\n", pl.l, &pl);
	}

	if (strlen(msg)) {
		DEBUG_WARNING("%u bytes junk at end: %s\n", strlen(msg), msg);
	}

	return !pl.l && !strlen(msg);
}
Beispiel #7
0
static void sipsess_info_handler(struct sip *sip, const struct sip_msg *msg,
				 void *arg)
{
	struct call *call = arg;

	if (msg_ctype_cmp(&msg->ctyp, "application", "dtmf-relay")) {

		struct pl body, sig, dur;
		int err;

		pl_set_mbuf(&body, msg->mb);

		err  = re_regex(body.p, body.l, "Signal=[0-9]+", &sig);
		err |= re_regex(body.p, body.l, "Duration=[0-9]+", &dur);

		if (err) {
			(void)sip_reply(sip, msg, 400, "Bad Request");
		}
		else {
			char s = pl_u32(&sig);
			uint32_t duration = pl_u32(&dur);

			if (s == 10) s = '*';
			else if (s == 11) s = '#';
			else s += '0';

			info("received DTMF: '%c' (duration=%r)\n", s, &dur);

			(void)sip_reply(sip, msg, 200, "OK");

			if (call->dtmfh) {
				tmr_start(&call->tmr_dtmf, duration,
					  dtmfend_handler, call);
				call->dtmfh(call, s, call->arg);
			}
		}
	}
#ifdef USE_VIDEO
	else if (msg_ctype_cmp(&msg->ctyp,
			       "application", "media_control+xml")) {
		call_handle_info_req(call, msg);
		(void)sip_reply(sip, msg, 200, "OK");
	}
#endif
	else {
		(void)sip_reply(sip, msg, 488, "Not Acceptable Here");
	}
}
Beispiel #8
0
static int attr_decode_rtpmap(struct sdp_media *m, const struct pl *pl)
{
	struct pl id, name, srate, ch;
	struct sdp_format *fmt;
	int err;

	if (!m)
		return 0;

	if (re_regex(pl->p, pl->l, "[^ ]+ [^/]+/[0-9]+[/]*[^]*",
		     &id, &name, &srate, NULL, &ch))
		return EBADMSG;

	fmt = sdp_format_find(&m->rfmtl, &id);
	if (!fmt)
		return 0;

	fmt->name = mem_deref(fmt->name);

	err = pl_strdup(&fmt->name, &name);
	if (err)
		return err;

	fmt->srate = pl_u32(&srate);
	fmt->ch = ch.l ? pl_u32(&ch) : 1;

	return 0;
}
Beispiel #9
0
static void sipsub_notify_handler(struct sip *sip, const struct sip_msg *msg,
				  void *arg)
{
	struct call *call = arg;
	struct pl scode, reason;
	uint32_t sc;

	if (re_regex((char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
		     "SIP/2.0 [0-9]+ [^\r\n]+", &scode, &reason)) {
		(void)sip_reply(sip, msg, 400, "Bad sipfrag");
		return;
	}

	(void)sip_reply(sip, msg, 200, "OK");

	sc = pl_u32(&scode);

	if (sc >= 300) {
		warning("call: transfer failed: %u %r\n", sc, &reason);
		call_event_handler(call, CALL_EVENT_TRANSFER_FAILED,
				   "%u %r", sc, &reason);
	}
	else if (sc >= 200) {
		call_event_handler(call, CALL_EVENT_CLOSED, "Call transfered");
	}
}
TEST_F(TestMedia, verify_sha256_fingerprint_in_offer)
{
	char sdp[4096];
	struct pl pl;
	size_t i;
	int err;

	err = mediaflow_generate_offer(mf, sdp, sizeof(sdp));
	ASSERT_EQ(0, err);

	ASSERT_TRUE(find_in_sdp(sdp, "fingerprint:sha-256"));
	ASSERT_TRUE(find_in_sdp(sdp, "setup:actpass"));

	err = re_regex(sdp, strlen(sdp), "fingerprint:sha-256 [^\r\n]+", &pl);
	ASSERT_EQ(0, err);

	/* Firefox has a strict SDP parser, hex values MUST be uppercase! */
	for (i=0; i<pl.l; i++) {

		char c = pl.p[i];

		if (c == ':' ||
		    ('0' <= c && c <= '9') ||
		    ('A' <= c && c <= 'F'))
			continue;

		re_fprintf(stderr, "invalid character in fingerprint (%r)\n", &pl);
		ASSERT_TRUE(false);
	}
}
Beispiel #11
0
int conf_get_vidsz(const struct conf *conf, const char *name, struct vidsz *sz)
{
	struct pl r, w, h;
	int err;

	err = conf_get(conf, name, &r);
	if (err)
		return err;

	w.l = h.l = 0;
	err = re_regex(r.p, r.l, "[0-9]+x[0-9]+", &w, &h);
	if (err)
		return err;

	if (pl_isset(&w) && pl_isset(&h)) {
		sz->w = pl_u32(&w);
		sz->h = pl_u32(&h);
	}

	/* check resolution */
	if (sz->w & 0x1 || sz->h & 0x1) {
		warning("conf: %s: should be multiple of 2 (%u x %u)\n",
			name, sz->w, sz->h);
		return EINVAL;
	}

	return 0;
}
Beispiel #12
0
/**
 * Apply a function handler to all config items of a certain key
 *
 * @param conf Configuration object
 * @param name Name of config item key
 * @param ch   Config item handler
 * @param arg  Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int conf_apply(const struct conf *conf, const char *name,
	       conf_h *ch, void *arg)
{
	char expr[512];
	struct pl pl, val;
	int err = 0;

	if (!conf || !name || !ch)
		return EINVAL;

	pl.p = (const char *)conf->mb->buf;
	pl.l = conf->mb->end;

	(void)re_snprintf(expr, sizeof(expr),
			  "[\r\n]+[ \t]*%s[ \t]+[~ \t\r\n]+", name);

	while (!re_regex(pl.p, pl.l, expr, NULL, NULL, NULL, &val)) {

		err = ch(&val, arg);
		if (err)
			break;

		pl.l -= val.p + val.l - pl.p;
		pl.p  = val.p + val.l;
	}

	return err;
}
Beispiel #13
0
/*
 * Start the audio loop (for testing)
 */
static int auloop_start(struct re_printf *pf, void *arg)
{
	struct cmd_arg *carg = arg;
	struct pl pl_srate, pl_ch;
	uint32_t srate, ch;
	int err;

	if (gal)
		return re_hprintf(pf, "audio-loop already running.\n");

	err = re_regex(carg->prm, str_len(carg->prm), "[0-9]+ [0-9]+",
		       &pl_srate, &pl_ch);
	if (err) {
		return re_hprintf(pf,
				  "Usage:"
				  " /auloop <samplerate> <channels>\n");
	}

	srate = pl_u32(&pl_srate);
	ch    = pl_u32(&pl_ch);
	if (!srate || !ch)
		return re_hprintf(pf, "invalid samplerate or channels\n");

	err = audio_loop_alloc(&gal, srate, ch);
	if (err) {
		warning("auloop: alloc failed %m\n", err);
	}

	return err;
}
Beispiel #14
0
static void decode_part(const struct pl *part, struct mbuf *mb)
{
	struct pl hdrs, body;

	if (re_regex(part->p, part->l, "\r\n\r\n[^]+", &body))
		return;

	hdrs.p = part->p;
	hdrs.l = body.p - part->p - 2;

	if (0 == re_regex(hdrs.p, hdrs.l, "application/sdp")) {

		mb->pos += (body.p - (char *)mbuf_buf(mb));
		mb->end  = mb->pos + body.l;
	}
}
Beispiel #15
0
static void sig_hash_decode(struct zrtp_stream_t *stream,
                           const struct sdp_media *m)
{
	const char *attr_val;
	struct pl major, minor, hash;
	uint32_t version;
	int err;
	zrtp_status_t s;

	attr_val = sdp_media_rattr(m, "zrtp-hash");
	if (!attr_val)
		return;

	err = re_regex(attr_val, strlen(attr_val),
	               "[0-9]+.[0-9]2 [0-9a-f]+",
	               &major, &minor, &hash);
	if (err || hash.l < ZRTP_SIGN_ZRTP_HASH_LENGTH) {
		warning("zrtp: malformed zrtp-hash attribute, ignoring...\n");
		return;
	}

	version = pl_u32(&major) * 100 + pl_u32(&minor);
	/* more version checks? */
	if (version < 110) {
		warning("zrtp: zrtp-hash: version (%d) is too low, "
		        "ignoring...", version);
	}

	s = zrtp_signaling_hash_set(stream, hash.p, (uint32_t)hash.l);
	if (s != zrtp_status_ok)
		warning("zrtp: zrtp_signaling_hash_set: status = %d\n", s);
}
Beispiel #16
0
/**
 * Decode an SDP fingerprint value
 *
 * @param attr SDP attribute value
 * @param hash Returned hash method
 * @param md   Returned message digest
 * @param sz   Message digest size, set on return
 *
 * @return 0 if success, otherwise errorcode
 *
 * Reference: RFC 4572
 */
int sdp_fingerprint_decode(const char *attr, struct pl *hash,
			   uint8_t *md, size_t *sz)
{
	struct pl f;
	const char *p;
	int err;

	if (!attr || !hash)
		return EINVAL;

	err = re_regex(attr, str_len(attr), "[^ ]+ [0-9A-F:]+", hash, &f);
	if (err)
		return err;

	if (md && sz) {
		if (*sz < (f.l+1)/3)
			return EOVERFLOW;

		for (p = f.p; p < (f.p+f.l); p += 3) {
			*md++ = ch_hex(p[0]) << 4 | ch_hex(p[1]);
		}

		*sz = (f.l+1)/3;
	}

	return 0;
}
TEST_F(TestMedia, sdp_offer_with_webrtc_rtp_profile)
{
	char sdp[4096];
	int err;

	err = mediaflow_add_video(mf, &vidcodecl);
	ASSERT_EQ(0, err);

	err = mediaflow_generate_offer(mf, sdp, sizeof(sdp));
	ASSERT_EQ(0, err);

	/* simple verification of SDP offer */
	ASSERT_EQ(0, re_regex(sdp, strlen(sdp),
			      "m=audio [0-9]+ UDP/TLS/RTP/SAVPF ", NULL));
	ASSERT_EQ(0, re_regex(sdp, strlen(sdp),
			      "m=video [0-9]+ UDP/TLS/RTP/SAVPF ", NULL));
}
Beispiel #18
0
static void decode_param(const struct pl *name, const struct pl *val,
			 void *arg)
{
	struct aucodec_st *st = arg;
	int err;

	if (0 == pl_strcasecmp(name, "bitrate")) {
		st->bitrate = pl_u32(val) * 1000;
	}
	else if (0 == pl_strcasecmp(name, "frame-size")) {
		st->frame_size = pl_u32(val);

		if (st->frame_size & 0x1) {
			DEBUG_WARNING("frame-size is NOT even: %u\n",
				      st->frame_size);
		}
	}
	else if (0 == pl_strcasecmp(name, "low-overhead")) {
		struct pl fs, bpfv;
		uint32_t i;

		st->low_overhead = true;

		err = re_regex(val->p, val->l, "[0-9]+/[0-9,]+", &fs, &bpfv);
		if (err)
			return;

		st->frame_size = pl_u32(&fs);

		for (i=0; i<ARRAY_SIZE(st->bpfv) && bpfv.l > 0; i++) {
			struct pl bpf, co;

			co.l = 0;
			if (re_regex(bpfv.p, bpfv.l, "[0-9]+[,]*", &bpf, &co))
				break;

			pl_advance(&bpfv, bpf.l + co.l);

			st->bpfv[i] = pl_u32(&bpf);
		}
		st->bpfn = i;
	}
	else {
		DEBUG_NOTICE("unknown param: %r = %r\n", name, val);
	}
}
Beispiel #19
0
int url_decode(struct url* url, struct pl *pl)
{
    int ok;
    ok = re_regex(pl->p, pl->l,
        "[^:]+://[^/]+[^]*", &url->scheme,
	&url->host, &url->path);
    url->port = 0;
    return 0;
}
Beispiel #20
0
static void tcp_recv_handler(struct mbuf *mb, void *arg)
{
    struct request *request = arg;
    int ok;

    struct pl ver;
    struct pl code;
    struct pl phrase;
    struct pl headers;
    struct pl body;

    DEBUG_INFO("recv data[%d]\n", mbuf_get_left(mb));

    if(request->state == STREAM) {
        request->stream_h(request, HTTP_STREAM_DATA, mb, request->arg);
        return;
    }

    if(request->body) {
        ok = mbuf_write_mem(request->body, mbuf_buf(mb), mbuf_get_left(mb));

        goto clen;
    }

    ok = re_regex((const char*)mbuf_buf(mb), mbuf_get_left(mb),
	"HTTP/[^ \t\r\n]+ [0-9]+ [^\t\r\n]+\r\n[^]1",
	&ver, &code, &phrase, &headers);

    // XXX: check ok
    // XXX: check headers.l

    request->status = pl_u32(&code);
    headers.l = mbuf_get_left(mb) - (headers.p - (const char*)mbuf_buf(mb));
    body.l = 0;
    parse_headers(request, (char*)headers.p, headers.l, &body);
    if(body.l) {
        request->body = mbuf_alloc(body.l);
        mbuf_write_mem(request->body, (const unsigned char*)body.p, body.l);
    }

    request->response = mem_ref(mb);

clen:
    if(request->body && request->clen > request->body->end)
	    return;

    if(request->status >= 200 || request->stream_h == NULL) {
        request->done_h(request, request->status, request->arg);
        request->state = END;
        mem_deref(request);
        return;
    }

    request->state = STREAM;
    request->stream_h(request, HTTP_STREAM_EST, mb, request->arg);
}
Beispiel #21
0
static int uri_complete(struct ua *ua, struct mbuf *buf, const char *uri)
{
	size_t len;
	int err = 0;

	/* Skip initial whitespace */
	while (isspace(*uri))
		++uri;

	len = str_len(uri);

	/* Append sip: scheme if missing */
	if (0 != re_regex(uri, len, "sip:"))
		err |= mbuf_printf(buf, "sip:");

	err |= mbuf_write_str(buf, uri);

	/* Append domain if missing */
	if (0 != re_regex(uri, len, "[^@]+@[^]+", NULL, NULL)) {
#if HAVE_INET6
		if (AF_INET6 == ua->acc->luri.af)
			err |= mbuf_printf(buf, "@[%r]",
					   &ua->acc->luri.host);
		else
#endif
			err |= mbuf_printf(buf, "@%r",
					   &ua->acc->luri.host);

		/* Also append port if specified and not 5060 */
		switch (ua->acc->luri.port) {

		case 0:
		case SIP_PORT:
			break;

		default:
			err |= mbuf_printf(buf, ":%u", ua->acc->luri.port);
			break;
		}
	}

	return err;
}
Beispiel #22
0
/*
 * Append module extension, if not exist
 *
 * input:    foobar
 * output:   foobar.so
 *
 */
static void append_extension(char *buf, size_t sz, const char *name)
{
	if (0 == re_regex(name, str_len(name), "[^.]+"MOD_EXT, NULL)) {

		str_ncpy(buf, name, sz);
	}
	else {
		re_snprintf(buf, sz, "%s"MOD_EXT, name);
	}
}
Beispiel #23
0
int sipevent_substate_decode(struct sipevent_substate *ss, const struct pl *pl)
{
	struct pl state, param;
	int err;

	if (!ss || !pl)
		return EINVAL;

	err = re_regex(pl->p, pl->l, "[a-z]+[ \t\r\n]*[^]*",
		       &state, NULL, &ss->params);
	if (err)
		return EBADMSG;

	if (!pl_strcasecmp(&state, "active"))
		ss->state = SIPEVENT_ACTIVE;
	else if (!pl_strcasecmp(&state, "pending"))
		ss->state = SIPEVENT_PENDING;
	else if (!pl_strcasecmp(&state, "terminated"))
		ss->state = SIPEVENT_TERMINATED;
	else
		ss->state = -1;

	if (!msg_param_decode(&ss->params, "reason", &param)) {

		if (!pl_strcasecmp(&param, "deactivated"))
			ss->reason = SIPEVENT_DEACTIVATED;
		else if (!pl_strcasecmp(&param, "probation"))
			ss->reason = SIPEVENT_PROBATION;
		else if (!pl_strcasecmp(&param, "rejected"))
			ss->reason = SIPEVENT_REJECTED;
		else if (!pl_strcasecmp(&param, "timeout"))
			ss->reason = SIPEVENT_TIMEOUT;
		else if (!pl_strcasecmp(&param, "giveup"))
			ss->reason = SIPEVENT_GIVEUP;
		else if (!pl_strcasecmp(&param, "noresource"))
			ss->reason = SIPEVENT_NORESOURCE;
		else
			ss->reason = -1;
	}
	else {
		ss->reason = -1;
	}

	if (!msg_param_decode(&ss->params, "expires", &param))
		ss->expires = param;
	else
		ss->expires = pl_null;

	if (!msg_param_decode(&ss->params, "retry-after", &param))
		ss->retry_after = param;
	else
		ss->retry_after = pl_null;

	return 0;
}
Beispiel #24
0
/**
 * Fetch a semicolon separated parameter from a PL string
 *
 * @param pl    PL string to search
 * @param pname Parameter name
 * @param val   Parameter value, set on return
 *
 * @return true if found, false if not found
 */
bool fmt_param_get(const struct pl *pl, const char *pname, struct pl *val)
{
	char expr[128];

	if (!pl)
		return false;

	(void)re_snprintf(expr, sizeof(expr), "%s[=]*[^;]*", pname);

	return 0 == re_regex(pl->p, pl->l, expr, NULL, val);
}
Beispiel #25
0
static int conn_decode(struct sa *sa, const struct pl *pl)
{
	struct pl v;

	if (re_regex(pl->p, pl->l, "IN IP[46]1 [^ ]+", NULL, &v))
		return EBADMSG;

	(void)sa_set(sa, &v, sa_port(sa));

	return 0;
}
Beispiel #26
0
static int attr_decode_rtcp(struct sdp_media *m, const struct pl *pl)
{
	struct pl port, addr;
	int err = 0;

	if (!m)
		return 0;

	if (!re_regex(pl->p, pl->l, "[0-9]+ IN IP[46]1 [^ ]+",
		      &port, NULL, &addr)) {
		(void)sa_set(&m->raddr_rtcp, &addr, pl_u32(&port));
	}
	else if (!re_regex(pl->p, pl->l, "[0-9]+", &port)) {
		sa_set_port(&m->raddr_rtcp, pl_u32(&port));
	}
	else
		err = EBADMSG;

	return err;
}
Beispiel #27
0
static void decoder_fmtp_decode(struct audec_state *st, const char *fmtp)
{
	struct pl mode;

	if (!fmtp)
		return;

	if (re_regex(fmtp, strlen(fmtp), "mode=[0-9]+", &mode))
		return;

	set_decoder_mode(st, pl_u32(&mode));
}
Beispiel #28
0
/**
 * Decode a multipart/mixed message and find the part with application/sdp
 *
 * @param ctype_prm  Content type parameter
 * @param mb         Mbuffer containing the SDP
 *
 * @return 0 if success, otherwise errorcode
 */
int sdp_decode_multipart(const struct pl *ctype_prm, struct mbuf *mb)
{
	struct pl bnd, s, e, p;
	char expr[64];
	int err;

	if (!ctype_prm || !mb)
		return EINVAL;

	/* fetch the boundary tag, excluding quotes */
	err = re_regex(ctype_prm->p, ctype_prm->l,
		       "boundary=[~]+", &bnd);
	if (err)
		return err;

	if (re_snprintf(expr, sizeof(expr), "--%r[^]+", &bnd) < 0)
		return ENOMEM;

	/* find 1st boundary */
	err = re_regex((char *)mbuf_buf(mb), mbuf_get_left(mb), expr, &s);
	if (err)
		return err;

	/* iterate over each part */
	while (s.l > 2) {
		if (re_regex(s.p, s.l, expr, &e))
			return 0;

		p.p = s.p + 2;
		p.l = e.p - p.p - bnd.l - 2;

		/* valid part in "p" */
		decode_part(&p, mb);

		s = e;
	}

	return 0;
}
Beispiel #29
0
/**
 * Get the value of a configuration item PL string
 *
 * @param conf Configuration object
 * @param name Name of config item key
 * @param pl   Value of config item, if present
 *
 * @return 0 if success, otherwise errorcode
 */
int conf_get(const struct conf *conf, const char *name, struct pl *pl)
{
	char expr[512];
	struct pl spl;

	if (!conf || !name || !pl)
		return EINVAL;

	spl.p = (const char *)conf->mb->buf;
	spl.l = conf->mb->end;

	(void)re_snprintf(expr, sizeof(expr),
			  "[\r\n]+[ \t]*%s[ \t]+[~ \t\r\n]+", name);

	return re_regex(spl.p, spl.l, expr, NULL, NULL, NULL, pl);
}
Beispiel #30
0
int cmd_process_long(struct commands *commands, const char *str, size_t len,
		     struct re_printf *pf_resp, void *data)
{
	struct cmd_arg arg;
	const struct cmd *cmd_long;
	char *name = NULL, *prm = NULL;
	struct pl pl_name, pl_prm;
	int err;

	if (!str || !len)
		return EINVAL;

	memset(&arg, 0, sizeof(arg));

	err = re_regex(str, len, "[^ ]+[ ]*[~]*", &pl_name, NULL, &pl_prm);
	if (err) {
		return err;
	}

	err = pl_strdup(&name, &pl_name);
	if (pl_isset(&pl_prm))
		err |= pl_strdup(&prm, &pl_prm);
	if (err)
		goto out;

	cmd_long = cmd_find_long(commands, name);
	if (cmd_long) {

		arg.key      = LONG_PREFIX;
		arg.prm      = prm;
		arg.complete = true;
		arg.data     = data;

		if (cmd_long->h)
			err = cmd_long->h(pf_resp, &arg);
	}
	else {
		err = re_hprintf(pf_resp, "command not found (%s)\n", name);
	}

 out:
	mem_deref(name);
	mem_deref(prm);

	return err;
}