/** * Apply a function handler to certain unknown SIP Headers * * @param msg SIP Message * @param fwd True to traverse forwards, false to traverse backwards * @param name SIP Header name * @param h Function handler * @param arg Handler argument * * @return SIP Header if handler returns true, otherwise NULL */ const struct sip_hdr *sip_msg_xhdr_apply(const struct sip_msg *msg, bool fwd, const char *name, sip_hdr_h *h, void *arg) { struct list *lst; struct le *le; struct pl pl; if (!msg || !name) return NULL; pl_set_str(&pl, name); lst = hash_list(msg->hdrht, hdr_hash(&pl)); le = fwd ? list_head(lst) : list_tail(lst); while (le) { const struct sip_hdr *hdr = le->data; le = fwd ? le->next : le->prev; if (pl_casecmp(&hdr->name, &pl)) continue; if (!h || h(hdr, msg, arg)) return hdr; } return NULL; }
/** * Apply a function handler to certain unknown HTTP Headers * * @param msg HTTP Message * @param fwd True to traverse forwards, false to traverse backwards * @param name HTTP Header name * @param h Function handler * @param arg Handler argument * * @return HTTP Header if handler returns true, otherwise NULL */ const struct http_hdr *http_msg_xhdr_apply(const struct http_msg *msg, bool fwd, const char *name, http_hdr_h *h, void *arg) { struct le *le; struct pl pl; if (!msg || !name) return NULL; pl_set_str(&pl, name); le = fwd ? msg->hdrl.head : msg->hdrl.tail; while (le) { const struct http_hdr *hdr = le->data; le = fwd ? le->next : le->prev; if (pl_casecmp(&hdr->name, &pl)) continue; if (!h || h(hdr, arg)) return hdr; } return NULL; }
static bool require_handler(const struct sip_hdr *hdr, const struct sip_msg *msg, void *arg) { struct ua *ua = arg; bool supported = false; size_t i; (void)msg; for (i=0; i<ua->extensionc; i++) { if (!pl_casecmp(&hdr->val, &ua->extensionv[i])) { supported = true; break; } } return !supported; }
/** * Find the correct UA from the contact user * * @param cuser Contact username * * @return Matching UA if found, NULL if not found */ struct ua *uag_find(const struct pl *cuser) { struct le *le; for (le = uag.ual.head; le; le = le->next) { struct ua *ua = le->data; if (0 == pl_strcasecmp(cuser, ua->cuser)) return ua; } /* Try also matching by AOR, for better interop */ for (le = uag.ual.head; le; le = le->next) { struct ua *ua = le->data; if (0 == pl_casecmp(cuser, &ua->acc->luri.user)) return ua; } return NULL; }
static int cmd_contact(struct re_printf *pf, void *arg) { const struct cmd_arg *carg = arg; struct contacts *contacts = baresip_contacts(); struct contact *cnt = NULL; struct pl dname, user, pl; struct le *le; int err = 0; pl_set_str(&pl, carg->prm); dname.l = user.l = pl.l; err |= re_hprintf(pf, "\n"); for (le = list_head(contact_list(contacts)); le; le = le->next) { struct contact *c = le->data; dname.p = contact_addr(c)->dname.p; user.p = contact_addr(c)->uri.user.p; /* if displayname is set, try to match the displayname * otherwise we try to match the username only */ if (dname.p) { if (0 == pl_casecmp(&dname, &pl)) { err |= re_hprintf(pf, "%s\n", contact_str(c)); cnt = c; } } else if (user.p) { if (0 == pl_casecmp(&user, &pl)) { err |= re_hprintf(pf, "%s\n", contact_str(c)); cnt = c; } } } if (!cnt) err |= re_hprintf(pf, "(no matches)\n"); if (carg->complete && cnt) { switch (carg->key) { case '|': err = ua_connect(uag_current(), NULL, NULL, contact_str(cnt), NULL, VIDMODE_ON); if (err) { warning("contact: ua_connect failed: %m\n", err); } break; case '=': chat_peer = contact_str(cnt); (void)re_hprintf(pf, "Selected chat peer: %s\n", chat_peer); re_snprintf(cmd_desc, sizeof(cmd_desc), "Send MESSAGE to %s", chat_peer); break; default: break; } } return err; }