/** * Get the path to configuration files * * @param path Buffer to write path * @param sz Size of path buffer * * @return 0 if success, otherwise errorcode */ int conf_path_get(char *path, size_t sz) { char buf[FS_PATH_MAX]; int err; /* Use explicit conf path */ if (conf_path) { if (re_snprintf(path, sz, "%s", conf_path) < 0) return ENOMEM; return 0; } #ifdef CONFIG_PATH str_ncpy(buf, CONFIG_PATH, sizeof(buf)); (void)err; #else err = fs_gethome(buf, sizeof(buf)); if (err) return err; #endif if (re_snprintf(path, sz, "%s" DIR_SEP ".baresip", buf) < 0) return ENOMEM; return 0; }
static void message_handler(const struct pl *peer, const struct pl *ctype, struct mbuf *body, void *arg) { (void)ctype; (void)arg; char message[256] = {0}; char s_peer[50] = {0}; struct contacts *contacts = baresip_contacts(); (void)re_snprintf(message, sizeof(message), "%b", mbuf_buf(body), mbuf_get_left(body)); (void)re_snprintf(s_peer, sizeof(s_peer), "%r", peer); warning("message from %s: %s\n", s_peer, message); struct contact *c = contact_find(contacts, s_peer); if (c) { const struct sip_addr *addr = contact_addr(c); (void)re_snprintf(s_peer, sizeof(s_peer), "%r", &addr->dname); (void)webapp_chat_add(s_peer, message, false); ws_send_json(WS_CHAT, webapp_messages_get()); } }
/** * Start registration of a User-Agent * * @param ua User-Agent * * @return 0 if success, otherwise errorcode */ int ua_register(struct ua *ua) { struct account *acc; struct le *le; struct uri uri; char reg_uri[64]; char params[256] = ""; unsigned i; int err; info("baresip.ua.ua_register()\n"); if (!ua) return EINVAL; acc = ua->acc; uri = ua->acc->luri; uri.user = uri.password = pl_null; if (re_snprintf(reg_uri, sizeof(reg_uri), "%H", uri_encode, &uri) < 0) return ENOMEM; if (str_isset(uag.cfg->uuid)) { if (re_snprintf(params, sizeof(params), ";+sip.instance=\"<urn:uuid:%s>\"", uag.cfg->uuid) < 0) return ENOMEM; } if (acc->regq) { if (re_snprintf(¶ms[strlen(params)], sizeof(params) - strlen(params), ";q=%s", acc->regq) < 0) return ENOMEM; } if (acc->mnat && acc->mnat->ftag) { if (re_snprintf(¶ms[strlen(params)], sizeof(params) - strlen(params), ";%s", acc->mnat->ftag) < 0) return ENOMEM; } ua_event(ua, UA_EVENT_REGISTERING, NULL, NULL); for (le = ua->regl.head, i=0; le; le = le->next, i++) { struct reg *reg = le->data; info("outbound[i]: "); info(acc->outbound[i]); err = reg_register(reg, reg_uri, params, acc->regint, acc->outbound[i]); if (err) { warning("ua: SIP register failed: %m\n", err); return err; } } return 0; }
static int module_init(void) { struct conf *conf = conf_cur(); uint32_t value; char *p = fmtp + str_len(fmtp); bool b; int n = 0; if (0 == conf_get_u32(conf, "opus_bitrate", &value)) { n = re_snprintf(p, sizeof(fmtp) - str_len(p), ";maxaveragebitrate=%d", value); if (n <= 0) return ENOMEM; p += n; } if (0 == conf_get_bool(conf, "opus_cbr", &b)) { n = re_snprintf(p, sizeof(fmtp) - str_len(p), ";cbr=%d", b); if (n <= 0) return ENOMEM; p += n; } if (0 == conf_get_bool(conf, "opus_inbandfec", &b)) { n = re_snprintf(p, sizeof(fmtp) - str_len(p), ";useinbandfec=%d", b); if (n <= 0) return ENOMEM; p += n; } if (0 == conf_get_bool(conf, "opus_dtx", &b)) { n = re_snprintf(p, sizeof(fmtp) - str_len(p), ";usedtx=%d", b); if (n <= 0) return ENOMEM; p += n; } (void)conf_get_bool(conf, "opus_mirror", &opus_mirror); debug("opus: fmtp=\"%s\"\n", fmtp); aucodec_register(&opus); return 0; }
static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { struct vidframe frame_rgb; int err = 0; if (!vidsz_cmp(&st->size, &frame->size)) { char capt[256]; if (st->size.w && st->size.h) { info("x11: reset: %u x %u ---> %u x %u\n", st->size.w, st->size.h, frame->size.w, frame->size.h); } if (st->internal && !st->win) err = create_window(st, &frame->size); err |= x11_reset(st, &frame->size); if (err) return err; if (title) { re_snprintf(capt, sizeof(capt), "%s - %u x %u", title, frame->size.w, frame->size.h); } else { re_snprintf(capt, sizeof(capt), "%u x %u", frame->size.w, frame->size.h); } XStoreName(st->disp, st->win, capt); } /* Convert from YUV420P to RGB */ vidframe_init_buf(&frame_rgb, st->pixfmt, &frame->size, (uint8_t *)st->shm.shmaddr); vidconv(&frame_rgb, frame, 0); /* draw */ if (st->xshmat) XShmPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h, false); else XPutImage(st->disp, st->win, st->gc, st->image, 0, 0, 0, 0, st->size.w, st->size.h); XSync(st->disp, false); return err; }
/** * Bind to a TCP Socket * * @param ts TCP Socket * @param local Local bind address * * @return 0 if success, otherwise errorcode */ int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local) { struct addrinfo hints, *res = NULL, *r; char addr[64] = ""; char serv[NI_MAXSERV] = "0"; int error, err; if (!ts || ts->fd<0) return EINVAL; if (local) { (void)re_snprintf(addr, sizeof(addr), "%H", sa_print_addr, local); (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(local)); } memset(&hints, 0, sizeof(hints)); /* set-up hints structure */ hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; error = getaddrinfo(addr[0] ? addr : NULL, serv, &hints, &res); if (error) { #ifdef WIN32 DEBUG_WARNING("sock_bind: getaddrinfo: wsaerr=%d\n", WSAGetLastError()); #endif DEBUG_WARNING("sock_bind: getaddrinfo: %s:%s error=%d (%s)\n", addr, serv, error, gai_strerror(error)); return EADDRNOTAVAIL; } err = EINVAL; for (r = res; r; r = r->ai_next) { if (bind(ts->fd, r->ai_addr, SIZ_CAST r->ai_addrlen) < 0) { err = errno; DEBUG_WARNING("sock_bind: bind: %m (af=%d, %J)\n", err, r->ai_family, local); continue; } /* OK */ err = 0; break; } freeaddrinfo(res); return err; }
static int update(struct aufilt_st **stp, struct aufilt *af, const struct aufilt_prm *encprm, const struct aufilt_prm *decprm) { char filename_enc[128], filename_dec[128]; SF_INFO sfinfo_enc, sfinfo_dec; struct sndfile_st *st; (void)af; st = mem_zalloc(sizeof(*st), sndfile_destructor); if (!st) return EINVAL; (void)re_snprintf(filename_enc, sizeof(filename_enc), "dump-%u-enc.wav", count); (void)re_snprintf(filename_dec, sizeof(filename_dec), "dump-%u-dec.wav", count); sfinfo_enc.samplerate = encprm->srate; sfinfo_enc.channels = encprm->ch; sfinfo_enc.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; sfinfo_dec.samplerate = decprm->srate; sfinfo_dec.channels = decprm->ch; sfinfo_dec.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; st->enc = sf_open(filename_enc, SFM_WRITE, &sfinfo_enc); if (!st->enc) { DEBUG_WARNING("could not open: %s\n", filename_enc); puts(sf_strerror(NULL)); goto error; } st->dec = sf_open(filename_dec, SFM_WRITE, &sfinfo_dec); if (!st->dec) { DEBUG_WARNING("could not open: %s\n", filename_dec); puts(sf_strerror(NULL)); goto error; } DEBUG_NOTICE("dumping audio to %s and %s\n", filename_enc, filename_dec); ++count; *stp = (struct aufilt_st *)st; return 0; error: mem_deref(st); return ENOMEM; }
/** * 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; }
static SNDFILE *openfile(const struct aufilt_prm *prm, bool enc) { char filename[128]; SF_INFO sfinfo; time_t tnow = time(0); struct tm *tm = localtime(&tnow); SNDFILE *sf; (void)re_snprintf(filename, sizeof(filename), "dump-%H-%s.wav", timestamp_print, tm, enc ? "enc" : "dec"); sfinfo.samplerate = prm->srate; sfinfo.channels = prm->ch; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; sf = sf_open(filename, SFM_WRITE, &sfinfo); if (!sf) { warning("sndfile: could not open: %s\n", filename); puts(sf_strerror(NULL)); return NULL; } info("sndfile: dumping %s audio to %s\n", enc ? "encode" : "decode", filename); return sf; }
static GtkMenuItem *accounts_menu_add_item(struct gtk_mod *mod, struct ua *ua) { GtkMenuShell *accounts_menu = GTK_MENU_SHELL(mod->accounts_menu); GtkWidget *item; GSList *group = mod->accounts_menu_group; struct ua *ua_current = uag_current(); char buf[256]; re_snprintf(buf, sizeof buf, "%s%s", ua_aor(ua), ua_isregistered(ua) ? " (OK)" : ""); item = gtk_radio_menu_item_new_with_label(group, buf); group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM (item)); if (ua == ua_current) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); g_object_set_data(G_OBJECT(item), "ua", ua); g_signal_connect(item, "toggled", G_CALLBACK(menu_on_account_toggled), mod); gtk_menu_shell_append(accounts_menu, item); mod->accounts_menu_group = group; return GTK_MENU_ITEM(item); }
static int module_init(void) { struct contacts *contacts = baresip_contacts(); char path[256] = "", file[256] = ""; int err; err = conf_path_get(path, sizeof(path)); if (err) return err; if (re_snprintf(file, sizeof(file), "%s/contacts", path) < 0) return ENOMEM; if (!conf_fileexist(file)) { (void)fs_mkdir(path, 0700); err = write_template(file); if (err) return err; } err = conf_parse(file, confline_handler, contacts); if (err) return err; err = cmd_register(baresip_commands(), cmdv, ARRAY_SIZE(cmdv)); if (err) return err; info("Populated %u contacts\n", list_count(contact_list(contacts))); return err; }
static bool contact_handler(const struct sip_hdr *hdr, const struct sip_msg *msg, void *arg) { struct sipreg *reg = arg; struct sip_addr c; struct pl pval; char uri[256]; if (sip_addr_decode(&c, &hdr->val)) return false; if (re_snprintf(uri, sizeof(uri), "sip:%s@%J%s", reg->cuser, ®->laddr, sip_transp_param(reg->tp)) < 0) return false; if (pl_strcmp(&c.auri, uri)) return false; if (!sip_param_decode(&c.params, "expires", &pval)) { reg->wait = pl_u32(&pval); } else if (pl_isset(&msg->expires)) reg->wait = pl_u32(&msg->expires); else reg->wait = DEFAULT_EXPIRES; return true; }
static void denotify_incoming_call(struct gtk_mod *mod, struct call *call) { GSList *item, *next; #if GLIB_CHECK_VERSION(2,40,0) char id[64]; re_snprintf(id, sizeof id, "incoming-call-%p", call); id[sizeof id - 1] = '\0'; g_application_withdraw_notification(mod->app, id); #endif /* Remove call submenu */ for (item = mod->incoming_call_menus; item; item = next) { GtkWidget *menu_item = item->data; next = item->next; if (call == g_object_get_data(G_OBJECT(menu_item), "call")) { gtk_widget_destroy(menu_item); mod->incoming_call_menus = g_slist_delete_link(mod->incoming_call_menus, item); } } }
/** * Play an audio file in WAV format * * @param playp Pointer to allocated player object * @param filename Name of WAV file to play * @param repeat Number of times to repeat * * @return 0 if success, otherwise errorcode */ int play_file(struct play **playp, const char *filename, int repeat) { struct mbuf *mb; char path[256]; uint32_t srate; uint8_t ch; int err; if (playp && *playp) return EALREADY; #ifndef PREFIX #define PREFIX "/usr" #endif if (re_snprintf(path, sizeof(path), PREFIX "/share/baresip/%s", filename) < 0) return ENOMEM; mb = mbuf_alloc(1024); if (!mb) return ENOMEM; err = aufile_load(mb, path, &srate, &ch); if (err) { DEBUG_WARNING("%s: %m\n", path, err); goto out; } err = play_tone(playp, mb, srate, ch, repeat); out: mem_deref(mb); return err; }
static const char *mknonce(char *nonce, uint32_t now, const struct sa *src) { (void)re_snprintf(nonce, NONCE_SIZE + 1, "%08x%08x", auth.rand_time ^ now, auth.rand_addr ^ sa_hash(src, SA_ADDR)); return nonce; }
static void on_zrtp_secure(zrtp_stream_t *stream) { const struct menc_media *st = zrtp_stream_get_userdata(stream); const struct menc_sess *sess = st->sess; zrtp_session_info_t sess_info; char buf[128] = ""; zrtp_session_get(sess->zrtp_session, &sess_info); if (!sess_info.sas_is_verified && sess_info.sas_is_ready) { info("zrtp: verify SAS <%s> <%s> for remote peer %w" " (type /zrtp_verify %w to verify)\n", sess_info.sas1.buffer, sess_info.sas2.buffer, sess_info.peer_zid.buffer, (size_t)sess_info.peer_zid.length, sess_info.peer_zid.buffer, (size_t)sess_info.peer_zid.length); if (sess->eventh) { if (re_snprintf(buf, sizeof(buf), "%s,%s,%w", sess_info.sas1.buffer, sess_info.sas2.buffer, sess_info.peer_zid.buffer, (size_t)sess_info.peer_zid.length)) (sess->eventh)(MENC_EVENT_VERIFY_REQUEST, buf, sess->arg); else warning("zrtp: failed to print verify " " arguments\n"); } } else if (sess_info.sas_is_verified) { info("zrtp: secure session with verified remote peer %w\n", sess_info.peer_zid.buffer, (size_t)sess_info.peer_zid.length); if (sess->eventh) { if (re_snprintf(buf, sizeof(buf), "%w", sess_info.peer_zid.buffer, (size_t)sess_info.peer_zid.length)) (sess->eventh)(MENC_EVENT_PEER_VERIFIED, buf, sess->arg); else warning("zrtp: failed to print verified " " argument\n"); } } }
static int module_init(void) { (void)re_snprintf(ilbc_fmtp, sizeof(ilbc_fmtp), "mode=%d", DEFAULT_MODE); aucodec_register(&ilbc); return 0; }
static void accounts_menu_set_status(struct gtk_mod *mod, struct ua *ua, enum ua_event ev) { GtkMenuItem *item = accounts_menu_get_item(mod, ua); char buf[256]; re_snprintf(buf, sizeof buf, "%s (%s)", ua_aor(ua), ua_event_reg_str(ev)); gtk_menu_item_set_label(item, buf); }
/* * 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); } }
static void message_handler(struct ua *ua, const struct pl *peer, const struct pl *ctype, struct mbuf *body, void *arg) { struct gtk_mod *mod = arg; char title[128]; char msg[512]; #if GLIB_CHECK_VERSION(2,40,0) GNotification *notification; #elif defined(USE_LIBNOTIFY) NotifyNotification *notification; #endif (void)ua; (void)ctype; /* Display notification of chat */ re_snprintf(title, sizeof title, "Chat from %r", peer); title[sizeof title - 1] = '\0'; re_snprintf(msg, sizeof msg, "%b", mbuf_buf(body), mbuf_get_left(body)); #if GLIB_CHECK_VERSION(2,40,0) notification = g_notification_new(title); g_notification_set_body(notification, msg); g_application_send_notification(mod->app, NULL, notification); g_object_unref(notification); #elif defined(USE_LIBNOTIFY) (void)mod; if (!notify_is_initted()) return; notification = notify_notification_new(title, msg, "baresip"); notify_notification_show(notification, NULL); g_object_unref(notification); #endif }
/** * 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); }
static int srv_lookup(struct sip_request *req, const char *domain) { char name[256]; if (re_snprintf(name, sizeof(name), "%s.%s", sip_transp_srvid(req->tp), domain) < 0) return ENOMEM; return dnsc_query(&req->dnsq, req->sip->dnsc, name, DNS_TYPE_SRV, DNS_CLASS_IN, true, srv_handler, req); }
static int array_entry_handler(unsigned idx, const struct json_value *val, void *arg) { struct odict *o = arg; char index[64]; if (re_snprintf(index, sizeof(index), "%u", idx) < 0) return ENOMEM; return entry_add(o, index, val); }
static const char* inet_ntop4(const u_char *src, char *dst, size_t size) { if (re_snprintf(dst, size, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]) < 0) { errno = ENOSPC; dst[size-1] = 0; return NULL; } return dst; }
void add_devices(size_t num) { char name[8]; for (size_t i=0; i<num; i++) { re_snprintf(name, sizeof(name), "%c", init_char++); err = device_alloc(NULL, &devicel, name); ASSERT_EQ(0, err); } }
static void draw_gradient(cairo_t *cr, double step, int width, int height) { cairo_pattern_t *pat; double r, g, b; double x, y, tx, ty; char buf[128]; double fontsize = 20.0; r = 0.1 + fabs(sin(5 * step)); g = 0.0; b = 0.1 + fabs(sin(3 * step)); x = width * (sin(10 * step) + 1)/2; y = height * (1 - fabs(sin(30 * step))); tx = width/2 * (sin(5 * step) + 1)/2; ty = fontsize + (height - fontsize) * (1 - fabs(sin(20 * step))); pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, height); cairo_pattern_add_color_stop_rgba (pat, 1, r, g, b, 1); cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1); cairo_rectangle (cr, 0, 0, width, height); cairo_set_source (cr, pat); cairo_fill (cr); cairo_pattern_destroy (pat); pat = cairo_pattern_create_radial (x-128, y-128, 25.6, x+128, y+128, 128.0); cairo_pattern_add_color_stop_rgba (pat, 0, 0, 1, 0, 1); cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1); cairo_set_source (cr, pat); cairo_arc (cr, x, y, 76.8, 0, 2 * M_PI); cairo_fill (cr); cairo_pattern_destroy (pat); /* Draw text */ cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, fontsize); re_snprintf(buf, sizeof(buf), "%H", fmt_gmtime, NULL); cairo_move_to (cr, tx, ty); cairo_text_path (cr, buf); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 0.1); cairo_stroke (cr); }
static int x64_strdup(char **strp, uint64_t val) { char *str; str = mem_alloc(X64_STRSIZE, NULL); if (!str) return ENOMEM; (void)re_snprintf(str, X64_STRSIZE, "%016llx", val); *strp = str; return 0; }
/** Foundation is a hash of IP address and candidate type */ static int compute_foundation(struct ice_lcand *cand, const struct sa *addr, enum ice_cand_type type) { uint32_t v; v = sa_hash(addr, SA_ADDR); v ^= type; if (re_snprintf(cand->attr.foundation, sizeof(cand->attr.foundation), "%08x", v) < 0) return ENOMEM; return 0; }
static int module_handler(const struct pl *val, void *arg) { struct pl *modpath = arg; char filepath[256]; struct mod *mod; int err; if (val->p && val->l && (*val->p == '/')) (void)re_snprintf(filepath, sizeof(filepath), "%r", val); else (void)re_snprintf(filepath, sizeof(filepath), "%r/%r", modpath, val); err = mod_load(&mod, filepath); if (err) { restund_warning("can't load module %s (%m)\n", filepath, err); goto out; } out: return err; }
static int module_init(void) { int err = 0; struct config *cfg = conf_config(); webapp_accounts_init(); #if defined (DARWIN) re_snprintf(command, sizeof(command), "open https://stream.studio-link.de/stream/login/%s", cfg->sip.uuid); #elif defined (WIN32) re_snprintf(command, sizeof(command), "start https://stream.studio-link.de/stream/login/%s", cfg->sip.uuid); #else re_snprintf(command, sizeof(command), "xdg-open https://stream.studio-link.de/stream/login/%s", cfg->sip.uuid); #endif tmr_init(&tmr); tmr_start(&tmr, 1500, startup, NULL); return err; }