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; }
static int dns_server_handler(const struct pl *pl, void *arg) { struct config_net *cfg = arg; const size_t max_count = ARRAY_SIZE(cfg->nsv); int err; if (cfg->nsc >= max_count) { warning("config: too many DNS nameservers (max %zu)\n", max_count); return EOVERFLOW; } /* Append dns_server to the network config */ err = pl_strcpy(pl, cfg->nsv[cfg->nsc].addr, sizeof(cfg->nsv[0].addr)); if (err) { warning("config: dns_server: could not copy string (%r)\n", pl); return err; } ++cfg->nsc; return 0; }
static int subscribe(struct presence *pres) { const char *routev[1]; struct ua *ua; char uri[256]; int err; /* We use the first UA */ ua = uag_find_aor(NULL); if (!ua) { warning("presence: no UA found\n"); return ENOENT; } pl_strcpy(&contact_addr(pres->contact)->auri, uri, sizeof(uri)); routev[0] = ua_outbound(ua); err = sipevent_subscribe(&pres->sub, uag_sipevent_sock(), uri, NULL, ua_aor(ua), "presence", NULL, 600, ua_cuser(ua), routev, routev[0] ? 1 : 0, auth_handler, ua_prm(ua), true, NULL, notify_handler, close_handler, pres, "%H", ua_print_supported, ua); if (err) { warning("presence: sipevent_subscribe failed: %m\n", err); } return err; }
/* Handle incoming calls */ static void sipsess_conn_handler(const struct sip_msg *msg, void *arg) { const struct sip_hdr *hdr; struct ua *ua; struct call *call = NULL; char to_uri[256]; int err; (void)arg; ua = uag_find(&msg->uri.user); if (!ua) { warning("ua: %r: UA not found: %r\n", &msg->from.auri, &msg->uri.user); (void)sip_treply(NULL, uag_sip(), msg, 404, "Not Found"); return; } /* handle multiple calls */ if (list_count(&ua->calls) + 1 > MAX_CALLS) { info("ua: rejected call from %r (maximum %d calls)\n", &msg->from.auri, MAX_CALLS); (void)sip_treply(NULL, uag.sip, msg, 486, "Busy Here"); return; } /* Handle Require: header, check for any required extensions */ hdr = sip_msg_hdr_apply(msg, true, SIP_HDR_REQUIRE, require_handler, ua); if (hdr) { info("ua: call from %r rejected with 420" " -- option-tag '%r' not supported\n", &msg->from.auri, &hdr->val); (void)sip_treplyf(NULL, NULL, uag.sip, msg, false, 420, "Bad Extension", "Unsupported: %r\r\n" "Content-Length: 0\r\n\r\n", &hdr->val); return; } (void)pl_strcpy(&msg->to.auri, to_uri, sizeof(to_uri)); err = ua_call_alloc(&call, ua, VIDMODE_ON, msg, NULL, to_uri); if (err) { warning("ua: call_alloc: %m\n", err); goto error; } err = call_accept(call, uag.sock, msg); if (err) goto error; return; error: mem_deref(call); (void)sip_treply(NULL, uag.sip, msg, 500, "Call Error"); }
/** * Add a User-Agent (UA) * * @param addr SIP Address string * * @return 0 if success, otherwise errorcode */ static int line_handler(const struct pl *addr) { char buf[512]; (void)pl_strcpy(addr, buf, sizeof(buf)); return ua_alloc(NULL, buf); }
int conf_get_csv(const struct conf *conf, const char *name, char *str1, size_t sz1, char *str2, size_t sz2) { struct pl r, pl1, pl2 = pl_null; int err; err = conf_get(conf, name, &r); if (err) return err; /* note: second value may be quoted */ err = re_regex(r.p, r.l, "[^,]+,[~]*", &pl1, &pl2); if (err) return err; (void)pl_strcpy(&pl1, str1, sz1); if (pl_isset(&pl2)) (void)pl_strcpy(&pl2, str2, sz2); return 0; }
/** * Get the value of a configuration item string * * @param conf Configuration object * @param name Name of config item key * @param str Value of config item, if present * @param size Size of string to store value * * @return 0 if success, otherwise errorcode */ int conf_get_str(const struct conf *conf, const char *name, char *str, size_t size) { struct pl pl; int err; if (!conf || !name || !str || !size) return EINVAL; err = conf_get(conf, name, &pl); if (err) return err; return pl_strcpy(&pl, str, size); }
static int load_module(struct mod **modp, const struct pl *modpath, const struct pl *name) { char file[FS_PATH_MAX]; char namestr[256]; struct mod *m = NULL; int err = 0; if (!name) return EINVAL; #ifdef STATIC /* Try static first */ pl_strcpy(name, namestr, sizeof(namestr)); if (mod_find(namestr)) { info("static module already loaded: %r\n", name); return EALREADY; } err = mod_add(&m, lookup_static_module(name)); if (!err) goto out; #else (void)namestr; #endif /* Then dynamic */ if (re_snprintf(file, sizeof(file), "%r/%r", modpath, name) < 0) { err = ENOMEM; goto out; } err = mod_load(&m, file); if (err) goto out; out: if (err) { warning("module %r: %m\n", name, err); } else if (modp) *modp = m; return err; }
int ice_cand_attr_decode(struct ice_cand_attr *cand, const char *val) { struct pl pl_fnd, pl_compid, pl_transp, pl_prio, pl_addr, pl_port; struct pl pl_type, pl_raddr, pl_rport, pl_opt = PL_INIT; size_t len; char type[8]; int err; if (!cand || !val) return EINVAL; memset(cand, 0, sizeof(*cand)); len = str_len(val); err = re_regex(val, len, "[^ ]+ [0-9]+ [a-z]+ [0-9]+ [^ ]+ [0-9]+ typ [a-z]+" "[^]*", &pl_fnd, &pl_compid, &pl_transp, &pl_prio, &pl_addr, &pl_port, &pl_type, &pl_opt); if (err) return err; (void)pl_strcpy(&pl_fnd, cand->foundation, sizeof(cand->foundation)); if (0 == pl_strcasecmp(&pl_transp, "UDP")) cand->proto = IPPROTO_UDP; else if (0 == pl_strcasecmp(&pl_transp, "TCP")) cand->proto = IPPROTO_TCP; else cand->proto = 0; err = sa_set(&cand->addr, &pl_addr, pl_u32(&pl_port)); if (err) return err; cand->compid = pl_u32(&pl_compid); cand->prio = pl_u32(&pl_prio); (void)pl_strcpy(&pl_type, type, sizeof(type)); cand->type = ice_cand_name2type(type); /* optional */ if (0 == re_regex(pl_opt.p, pl_opt.l, "raddr [^ ]+ rport [0-9]+", &pl_raddr, &pl_rport)) { err = sa_set(&cand->rel_addr, &pl_raddr, pl_u32(&pl_rport)); if (err) return err; } if (cand->proto == IPPROTO_TCP) { struct pl tcptype; err = re_regex(pl_opt.p, pl_opt.l, "tcptype [^ ]+", &tcptype); if (err) return err; cand->tcptype = ice_tcptype_resolve(&tcptype); } return 0; }
static int cand_decode(struct icem *icem, const char *val) { struct pl foundation, compid, transp, prio, addr, port, cand_type; struct pl extra = pl_null; struct sa caddr, rel_addr; char type[8]; uint8_t cid; int err; sa_init(&rel_addr, AF_INET); err = re_regex(val, strlen(val), "[^ ]+ [0-9]+ [^ ]+ [0-9]+ [^ ]+ [0-9]+ typ [a-z]+[^]*", &foundation, &compid, &transp, &prio, &addr, &port, &cand_type, &extra); if (err) return err; if (ICE_TRANSP_NONE == transp_resolve(&transp)) { DEBUG_NOTICE("<%s> ignoring candidate with" " unknown transport=%r (%r:%r)\n", icem->name, &transp, &cand_type, &addr); return 0; } if (pl_isset(&extra)) { struct pl name, value; /* Loop through " SP attr SP value" pairs */ while (!re_regex(extra.p, extra.l, " [^ ]+ [^ ]+", &name, &value)) { pl_advance(&extra, value.p + value.l - extra.p); if (0 == pl_strcasecmp(&name, rel_addr_str)) { err = sa_set(&rel_addr, &value, sa_port(&rel_addr)); if (err) break; } else if (0 == pl_strcasecmp(&name, rel_port_str)) { sa_set_port(&rel_addr, pl_u32(&value)); } } } err = sa_set(&caddr, &addr, pl_u32(&port)); if (err) return err; cid = pl_u32(&compid); /* add only if not exist */ if (icem_cand_find(&icem->rcandl, cid, &caddr)) return 0; (void)pl_strcpy(&cand_type, type, sizeof(type)); return icem_rcand_add(icem, ice_cand_name2type(type), cid, pl_u32(&prio), &caddr, &rel_addr, &foundation); }