static int rtsp_exec(pa_rtsp_client *c, const char *cmd, const char *content_type, const char *content, int expect_response, pa_headerlist *headers) { pa_strbuf *buf; char *hdrs; pa_assert(c); pa_assert(c->url); pa_assert(cmd); pa_assert(c->ioline); pa_log_debug("Sending command: %s", cmd); buf = pa_strbuf_new(); pa_strbuf_printf(buf, "%s %s RTSP/1.0\r\nCSeq: %d\r\n", cmd, c->url, ++c->cseq); if (c->session) pa_strbuf_printf(buf, "Session: %s\r\n", c->session); /* Add the headers */ if (headers) { hdrs = pa_headerlist_to_string(headers); pa_strbuf_puts(buf, hdrs); pa_xfree(hdrs); } if (content_type && content) { pa_strbuf_printf(buf, "Content-Type: %s\r\nContent-Length: %d\r\n", content_type, (int)strlen(content)); } pa_strbuf_printf(buf, "User-Agent: %s\r\n", c->useragent); if (c->headers) { hdrs = pa_headerlist_to_string(c->headers); pa_strbuf_puts(buf, hdrs); pa_xfree(hdrs); } pa_strbuf_puts(buf, "\r\n"); if (content_type && content) { pa_strbuf_puts(buf, content); } /* Our packet is created... now we can send it :) */ hdrs = pa_strbuf_to_string_free(buf); /*pa_log_debug("Submitting request:"); pa_log_debug(hdrs);*/ pa_ioline_puts(c->ioline, hdrs); pa_xfree(hdrs); /* The command is sent we can configure the rtsp client structure to handle a new answer */ c->waiting = 1; return 0; }
static void append_port_list(pa_strbuf *s, pa_hashmap *ports) { pa_device_port *p; void *state; if (!ports) return; pa_strbuf_puts(s, "\tports:\n"); PA_HASHMAP_FOREACH(p, ports, state) pa_strbuf_printf(s, "\t\t%s: %s (priority %u, available: %s)\n", p->name, p->description, p->priority, port_available_to_string(p->available)); }
char *pa_full_status_string(pa_core *c) { pa_strbuf *s; int i; s = pa_strbuf_new(); for (i = 0; i < 8; i++) { char *t = NULL; switch (i) { case 0: t = pa_sink_list_to_string(c); break; case 1: t = pa_source_list_to_string(c); break; case 2: t = pa_sink_input_list_to_string(c); break; case 3: t = pa_source_output_list_to_string(c); break; case 4: t = pa_client_list_to_string(c); break; case 5: t = pa_module_list_to_string(c); break; case 6: t = pa_scache_list_to_string(c); break; case 7: t = pa_autoload_list_to_string(c); break; } pa_strbuf_puts(s, t); pa_xfree(t); } return pa_strbuf_tostring_free(s); }
static void line_callback(pa_ioline *line, const char *s, void *userdata) { char *delimpos; char *s2, *s2p; pa_rtsp_client *c = userdata; pa_assert(line); pa_assert(c); pa_assert(c->callback); if (!s) { /* Keep the ioline/iochannel open as they will be freed automatically */ c->ioline = NULL; c->callback(c, STATE_DISCONNECTED, NULL, c->userdata); return; } s2 = pa_xstrdup(s); /* Trim trailing carriage returns */ s2p = s2 + strlen(s2) - 1; while (s2p >= s2 && '\r' == *s2p) { *s2p = '\0'; s2p -= 1; } if (c->waiting && 0 == strcmp("RTSP/1.0 200 OK", s2)) { c->waiting = 0; if (c->response_headers) pa_headerlist_free(c->response_headers); c->response_headers = pa_headerlist_new(); goto exit; } if (c->waiting) { pa_log_warn("Unexpected response: %s", s2); goto exit;; } if (!strlen(s2)) { /* End of headers */ /* We will have a header left from our looping iteration, so add it in :) */ if (c->last_header) { char *tmp = pa_strbuf_tostring_free(c->header_buffer); /* This is not a continuation header so let's dump it into our proplist */ pa_headerlist_puts(c->response_headers, c->last_header, tmp); pa_xfree(tmp); pa_xfree(c->last_header); c->last_header = NULL; c->header_buffer = NULL; } pa_log_debug("Full response received. Dispatching"); headers_read(c); c->waiting = 1; goto exit; } /* Read and parse a header (we know it's not empty) */ /* TODO: Move header reading into the headerlist. */ /* If the first character is a space, it's a continuation header */ if (c->last_header && ' ' == s2[0]) { pa_assert(c->header_buffer); /* Add this line to the buffer (sans the space. */ pa_strbuf_puts(c->header_buffer, &(s2[1])); goto exit; } if (c->last_header) { char *tmp = pa_strbuf_tostring_free(c->header_buffer); /* This is not a continuation header so let's dump the full header/value into our proplist */ pa_headerlist_puts(c->response_headers, c->last_header, tmp); pa_xfree(tmp); pa_xfree(c->last_header); c->last_header = NULL; c->header_buffer = NULL; } delimpos = strstr(s2, ":"); if (!delimpos) { pa_log_warn("Unexpected response when expecting header: %s", s); goto exit; } pa_assert(!c->header_buffer); pa_assert(!c->last_header); c->header_buffer = pa_strbuf_new(); if (strlen(delimpos) > 1) { /* Cut our line off so we can copy the header name out */ *delimpos++ = '\0'; /* Trim the front of any spaces */ while (' ' == *delimpos) ++delimpos; pa_strbuf_puts(c->header_buffer, delimpos); } else { /* Cut our line off so we can copy the header name out */ *delimpos = '\0'; } /* Save the header name */ c->last_header = pa_xstrdup(s2); exit: pa_xfree(s2); }
int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) { pa_strbuf *buf = NULL; int c; int b; pa_assert(conf); pa_assert(argc > 0); pa_assert(argv); buf = pa_strbuf_new(); if (conf->script_commands) pa_strbuf_puts(buf, conf->script_commands); while ((c = getopt_long(argc, argv, "L:F:ChDnp:kv", long_options, NULL)) != -1) { switch (c) { case ARG_HELP: case 'h': conf->cmd = PA_CMD_HELP; break; case ARG_VERSION: conf->cmd = PA_CMD_VERSION; break; case ARG_DUMP_CONF: conf->cmd = PA_CMD_DUMP_CONF; break; case ARG_DUMP_MODULES: conf->cmd = PA_CMD_DUMP_MODULES; break; case ARG_DUMP_RESAMPLE_METHODS: conf->cmd = PA_CMD_DUMP_RESAMPLE_METHODS; break; case ARG_CLEANUP_SHM: conf->cmd = PA_CMD_CLEANUP_SHM; break; case 'k': case ARG_KILL: conf->cmd = PA_CMD_KILL; break; case ARG_START: conf->cmd = PA_CMD_START; conf->daemonize = true; break; case ARG_CHECK: conf->cmd = PA_CMD_CHECK; break; case ARG_LOAD: case 'L': pa_strbuf_printf(buf, "load-module %s\n", optarg); break; case ARG_FILE: case 'F': { char *p; pa_strbuf_printf(buf, ".include %s\n", p = pa_make_path_absolute(optarg)); pa_xfree(p); break; } case 'C': pa_strbuf_puts(buf, "load-module module-cli exit_on_eof=1\n"); break; case ARG_DAEMONIZE: case 'D': if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--daemonize expects boolean argument")); goto fail; } conf->daemonize = !!b; break; case ARG_FAIL: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--fail expects boolean argument")); goto fail; } conf->fail = !!b; break; case 'v': case ARG_LOG_LEVEL: if (optarg) { if (pa_daemon_conf_set_log_level(conf, optarg) < 0) { pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error).")); goto fail; } } else { if (conf->log_level < PA_LOG_LEVEL_MAX-1) conf->log_level++; } break; case ARG_HIGH_PRIORITY: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--high-priority expects boolean argument")); goto fail; } conf->high_priority = !!b; break; case ARG_REALTIME: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--realtime expects boolean argument")); goto fail; } conf->realtime_scheduling = !!b; break; case ARG_DISALLOW_MODULE_LOADING: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--disallow-module-loading expects boolean argument")); goto fail; } conf->disallow_module_loading = !!b; break; case ARG_DISALLOW_EXIT: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--disallow-exit expects boolean argument")); goto fail; } conf->disallow_exit = !!b; break; case ARG_USE_PID_FILE: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--use-pid-file expects boolean argument")); goto fail; } conf->use_pid_file = !!b; break; case 'p': case ARG_DL_SEARCH_PATH: pa_xfree(conf->dl_search_path); conf->dl_search_path = pa_xstrdup(optarg); break; case 'n': conf->load_default_script_file = false; break; case ARG_LOG_TARGET: if (pa_daemon_conf_set_log_target(conf, optarg) < 0) { #ifdef HAVE_SYSTEMD_JOURNAL pa_log(_("Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'.")); #else pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'.")); #endif goto fail; } break; case ARG_LOG_TIME: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--log-time expects boolean argument")); goto fail; } conf->log_time = !!b; break; case ARG_LOG_META: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--log-meta expects boolean argument")); goto fail; } conf->log_meta = !!b; break; case ARG_LOG_BACKTRACE: conf->log_backtrace = (unsigned) atoi(optarg); break; case ARG_EXIT_IDLE_TIME: conf->exit_idle_time = atoi(optarg); break; case ARG_SCACHE_IDLE_TIME: conf->scache_idle_time = atoi(optarg); break; case ARG_RESAMPLE_METHOD: if (pa_daemon_conf_set_resample_method(conf, optarg) < 0) { pa_log(_("Invalid resample method '%s'."), optarg); goto fail; } break; case ARG_SYSTEM: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--system expects boolean argument")); goto fail; } conf->system_instance = !!b; break; case ARG_NO_CPU_LIMIT: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--no-cpu-limit expects boolean argument")); goto fail; } conf->no_cpu_limit = !!b; break; case ARG_DISABLE_SHM: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--disable-shm expects boolean argument")); goto fail; } conf->disable_shm = !!b; break; case ARG_ENABLE_MEMFD: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--enable-memfd expects boolean argument")); goto fail; } conf->disable_memfd = !b; break; default: goto fail; } } pa_xfree(conf->script_commands); conf->script_commands = pa_strbuf_to_string_free(buf); *d = optind; return 0; fail: if (buf) pa_strbuf_free(buf); return -1; }
char *pa_card_list_to_string(pa_core *c) { pa_strbuf *s; pa_card *card; uint32_t idx = PA_IDXSET_INVALID; pa_assert(c); s = pa_strbuf_new(); pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(c->cards)); for (card = pa_idxset_first(c->cards, &idx); card; card = pa_idxset_next(c->cards, &idx)) { char *t; pa_sink *sink; pa_source *source; uint32_t sidx; pa_strbuf_printf( s, " index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n", card->index, card->name, card->driver); if (card->module) pa_strbuf_printf(s, "\towner module: %u\n", card->module->index); t = pa_proplist_to_string_sep(card->proplist, "\n\t\t"); pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); pa_xfree(t); if (card->profiles) { pa_card_profile *p; void *state; pa_strbuf_puts(s, "\tprofiles:\n"); PA_HASHMAP_FOREACH(p, card->profiles, state) pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority); } if (card->active_profile) pa_strbuf_printf( s, "\tactive profile: <%s>\n", card->active_profile->name); if (!pa_idxset_isempty(card->sinks)) { pa_strbuf_puts(s, "\tsinks:\n"); for (sink = pa_idxset_first(card->sinks, &sidx); sink; sink = pa_idxset_next(card->sinks, &sidx)) pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", sink->name, sink->index, pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION))); } if (!pa_idxset_isempty(card->sources)) { pa_strbuf_puts(s, "\tsources:\n"); for (source = pa_idxset_first(card->sources, &sidx); source; source = pa_idxset_next(card->sources, &sidx)) pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", source->name, source->index, pa_strna(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION))); } append_port_list(s, card->ports); } return pa_strbuf_tostring_free(s); }