2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
34 #include <pulse/xmalloc.h>
35 #include <pulse/error.h>
37 #include <pulsecore/module.h>
38 #include <pulsecore/sink.h>
39 #include <pulsecore/source.h>
40 #include <pulsecore/client.h>
41 #include <pulsecore/sink-input.h>
42 #include <pulsecore/source-output.h>
43 #include <pulsecore/tokenizer.h>
44 #include <pulsecore/strbuf.h>
45 #include <pulsecore/namereg.h>
46 #include <pulsecore/cli-text.h>
47 #include <pulsecore/core-scache.h>
48 #include <pulsecore/sample-util.h>
49 #include <pulsecore/sound-file.h>
50 #include <pulsecore/play-memchunk.h>
51 #include <pulsecore/sound-file-stream.h>
52 #include <pulsecore/shared.h>
53 #include <pulsecore/core-util.h>
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/modinfo.h>
57 #include "cli-command.h"
61 int (*proc) (pa_core *c, pa_tokenizer*t, pa_strbuf *buf, pa_bool_t *fail);
66 #define META_INCLUDE ".include"
67 #define META_FAIL ".fail"
68 #define META_NOFAIL ".nofail"
69 #define META_IFEXISTS ".ifexists"
70 #define META_ELSE ".else"
71 #define META_ENDIF ".endif"
79 /* Prototypes for all available commands */
80 static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
81 static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
82 static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
83 static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
84 static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
85 static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
86 static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
87 static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
88 static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
89 static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
90 static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
91 static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
92 static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
93 static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
94 static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
95 static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
96 static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
97 static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
98 static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
99 static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
100 static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
101 static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
102 static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
103 static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
104 static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
105 static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
106 static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
107 static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
108 static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
109 static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
110 static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
111 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
112 static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
113 static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
114 static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
115 static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
116 static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
117 static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
118 static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
119 static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
120 static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
121 static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
122 static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
123 static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
124 static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
125 static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
126 static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
127 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
129 /* A method table for all available commands */
131 static const struct command commands[] = {
132 { "exit", pa_cli_command_exit, "Terminate the daemon", 1 },
133 { "help", pa_cli_command_help, "Show this help", 1 },
134 { "list-modules", pa_cli_command_modules, "List loaded modules", 1 },
135 { "list-sinks", pa_cli_command_sinks, "List loaded sinks", 1 },
136 { "list-sources", pa_cli_command_sources, "List loaded sources", 1 },
137 { "list-clients", pa_cli_command_clients, "List loaded clients", 1 },
138 { "list-sink-inputs", pa_cli_command_sink_inputs, "List sink inputs", 1 },
139 { "list-source-outputs", pa_cli_command_source_outputs, "List source outputs", 1 },
140 { "list-cards", pa_cli_command_cards, "List cards", 1 },
141 { "stat", pa_cli_command_stat, "Show memory block statistics", 1 },
142 { "info", pa_cli_command_info, "Show comprehensive status", 1 },
143 { "ls", pa_cli_command_info, NULL, 1 },
144 { "list", pa_cli_command_info, NULL, 1 },
145 { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3},
146 { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2},
147 { "describe-module", pa_cli_command_describe, "Describe a module (arg: name)", 2},
148 { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3},
149 { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index, volume)", 3},
150 { "set-source-volume", pa_cli_command_source_volume, "Set the volume of a source (args: index|name, volume)", 3},
151 { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, bool)", 3},
152 { "set-sink-input-mute", pa_cli_command_sink_input_mute, "Set the mute switch of a sink input (args: index, bool)", 3},
153 { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, bool)", 3},
154 { "update-sink-proplist", pa_cli_command_update_sink_proplist, "Update the properties of a sink (args: index|name, properties)", 3},
155 { "update-source-proplist", pa_cli_command_update_source_proplist, "Update the properties of a source (args: index|name, properties)", 3},
156 { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist, "Update the properties of a sink input (args: index, properties)", 3},
157 { "update-source-output-proplist", pa_cli_command_update_source_output_proplist, "Update the properties of a source_output (args: index, properties)", 3},
158 { "set-default-sink", pa_cli_command_sink_default, "Set the default sink (args: index|name)", 2},
159 { "set-default-source", pa_cli_command_source_default, "Set the default source (args: index|name)", 2},
160 { "kill-client", pa_cli_command_kill_client, "Kill a client (args: index)", 2},
161 { "kill-sink-input", pa_cli_command_kill_sink_input, "Kill a sink input (args: index)", 2},
162 { "kill-source-output", pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2},
163 { "list-samples", pa_cli_command_scache_list, "List all entries in the sample cache", 1},
164 { "play-sample", pa_cli_command_scache_play, "Play a sample from the sample cache (args: name, sink|index)", 3},
165 { "remove-sample", pa_cli_command_scache_remove, "Remove a sample from the sample cache (args: name)", 2},
166 { "load-sample", pa_cli_command_scache_load, "Load a sound file into the sample cache (args: name, filename)", 3},
167 { "load-sample-lazy", pa_cli_command_scache_load, "Lazily load a sound file into the sample cache (args: name, filename)", 3},
168 { "load-sample-dir-lazy", pa_cli_command_scache_load_dir, "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
169 { "play-file", pa_cli_command_play_file, "Play a sound file (args: filename, sink|index)", 3},
170 { "dump", pa_cli_command_dump, "Dump daemon configuration", 1},
171 { "shared", pa_cli_command_list_shared_props, NULL, 1},
172 { "move-sink-input", pa_cli_command_move_sink_input, "Move sink input to another sink (args: index, sink)", 3},
173 { "move-source-output", pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3},
174 { "vacuum", pa_cli_command_vacuum, NULL, 1},
175 { "suspend-sink", pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3},
176 { "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3},
177 { "suspend", pa_cli_command_suspend, "Suspend all sinks and all sources (args: bool)", 2},
178 { "set-card-profile", pa_cli_command_card_profile, "Change the profile of a card (args: index, name)", 3},
179 { "set-log-level", pa_cli_command_log_level, "Change the log level (args: numeric level)", 2},
180 { "set-log-meta", pa_cli_command_log_meta, "Show source code location in log messages (args: bool)", 2},
181 { "set-log-time", pa_cli_command_log_time, "Show timestamps in log messages (args: bool)", 2},
182 { "set-log-backtrace", pa_cli_command_log_backtrace, "Show bakctrace in log messages (args: frames)", 2},
183 { NULL, NULL, NULL, 0 }
186 static const char whitespace[] = " \t\n\r";
187 static const char linebreak[] = "\n\r";
189 static uint32_t parse_index(const char *n) {
192 if (pa_atou(n, &idx) < 0)
193 return (uint32_t) PA_IDXSET_INVALID;
198 static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
199 pa_core_assert_ref(c);
204 if (pa_core_exit(c, FALSE, 0) < 0)
205 pa_strbuf_puts(buf, "Not allowed to terminate daemon.\n");
210 static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
211 const struct command*command;
213 pa_core_assert_ref(c);
218 pa_strbuf_puts(buf, "Available commands:\n");
220 for (command = commands; command->name; command++)
222 pa_strbuf_printf(buf, " %-25s %s\n", command->name, command->help);
226 static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
229 pa_core_assert_ref(c);
234 pa_assert_se(s = pa_module_list_to_string(c));
235 pa_strbuf_puts(buf, s);
240 static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
243 pa_core_assert_ref(c);
248 pa_assert_se(s = pa_client_list_to_string(c));
249 pa_strbuf_puts(buf, s);
254 static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
257 pa_core_assert_ref(c);
262 pa_assert_se(s = pa_card_list_to_string(c));
263 pa_strbuf_puts(buf, s);
268 static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
271 pa_core_assert_ref(c);
276 pa_assert_se(s = pa_sink_list_to_string(c));
277 pa_strbuf_puts(buf, s);
282 static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
285 pa_core_assert_ref(c);
290 pa_assert_se(s = pa_source_list_to_string(c));
291 pa_strbuf_puts(buf, s);
296 static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
299 pa_core_assert_ref(c);
304 pa_assert_se(s = pa_sink_input_list_to_string(c));
305 pa_strbuf_puts(buf, s);
310 static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
313 pa_core_assert_ref(c);
318 pa_assert_se(s = pa_source_output_list_to_string(c));
319 pa_strbuf_puts(buf, s);
324 static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
325 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
326 char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
328 const pa_mempool_stat *stat;
331 pa_source *def_source;
333 static const char* const type_table[PA_MEMBLOCK_TYPE_MAX] = {
334 [PA_MEMBLOCK_POOL] = "POOL",
335 [PA_MEMBLOCK_POOL_EXTERNAL] = "POOL_EXTERNAL",
336 [PA_MEMBLOCK_APPENDED] = "APPENDED",
337 [PA_MEMBLOCK_USER] = "USER",
338 [PA_MEMBLOCK_FIXED] = "FIXED",
339 [PA_MEMBLOCK_IMPORTED] = "IMPORTED",
342 pa_core_assert_ref(c);
347 stat = pa_mempool_get_stat(c->mempool);
349 pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
350 (unsigned) pa_atomic_load(&stat->n_allocated),
351 pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->allocated_size)));
353 pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
354 (unsigned) pa_atomic_load(&stat->n_accumulated),
355 pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->accumulated_size)));
357 pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
358 (unsigned) pa_atomic_load(&stat->n_imported),
359 pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->imported_size)));
361 pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
362 (unsigned) pa_atomic_load(&stat->n_exported),
363 pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->exported_size)));
365 pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
366 pa_bytes_snprint(s, sizeof(s), (unsigned) pa_scache_total_size(c)));
368 pa_strbuf_printf(buf, "Default sample spec: %s\n",
369 pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec));
371 pa_strbuf_printf(buf, "Default channel map: %s\n",
372 pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
374 def_sink = pa_namereg_get_default_sink(c);
375 def_source = pa_namereg_get_default_source(c);
376 pa_strbuf_printf(buf, "Default sink name: %s\n"
377 "Default source name: %s\n",
378 def_sink ? def_sink->name : "none",
379 def_source ? def_source->name : "none");
381 for (k = 0; k < PA_MEMBLOCK_TYPE_MAX; k++)
382 pa_strbuf_printf(buf,
383 "Memory blocks of type %s: %u allocated/%u accumulated.\n",
385 (unsigned) pa_atomic_load(&stat->n_allocated_by_type[k]),
386 (unsigned) pa_atomic_load(&stat->n_accumulated_by_type[k]));
391 static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
392 pa_core_assert_ref(c);
397 pa_cli_command_stat(c, t, buf, fail);
398 pa_cli_command_modules(c, t, buf, fail);
399 pa_cli_command_sinks(c, t, buf, fail);
400 pa_cli_command_sources(c, t, buf, fail);
401 pa_cli_command_clients(c, t, buf, fail);
402 pa_cli_command_cards(c, t, buf, fail);
403 pa_cli_command_sink_inputs(c, t, buf, fail);
404 pa_cli_command_source_outputs(c, t, buf, fail);
405 pa_cli_command_scache_list(c, t, buf, fail);
409 static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
412 pa_core_assert_ref(c);
417 if (!(name = pa_tokenizer_get(t, 1))) {
418 pa_strbuf_puts(buf, "You need to specify the module name and optionally arguments.\n");
422 if (!pa_module_load(c, name, pa_tokenizer_get(t, 2))) {
423 pa_strbuf_puts(buf, "Module load failed.\n");
430 static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
436 pa_core_assert_ref(c);
441 if (!(i = pa_tokenizer_get(t, 1))) {
442 pa_strbuf_puts(buf, "You need to specify the module index.\n");
446 idx = (uint32_t) strtoul(i, &e, 10);
447 if (*e || !(m = pa_idxset_get_by_index(c->modules, idx))) {
448 pa_strbuf_puts(buf, "Invalid module index.\n");
452 pa_module_unload_request(m, FALSE);
456 static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
460 pa_core_assert_ref(c);
465 if (!(name = pa_tokenizer_get(t, 1))) {
466 pa_strbuf_puts(buf, "You need to specify the module name.\n");
470 if ((i = pa_modinfo_get_by_name(name))) {
472 pa_strbuf_printf(buf, "Name: %s\n", name);
474 if (!i->description && !i->version && !i->author && !i->usage)
475 pa_strbuf_printf(buf, "No module information available\n");
478 pa_strbuf_printf(buf, "Version: %s\n", i->version);
480 pa_strbuf_printf(buf, "Description: %s\n", i->description);
482 pa_strbuf_printf(buf, "Author: %s\n", i->author);
484 pa_strbuf_printf(buf, "Usage: %s\n", i->usage);
485 pa_strbuf_printf(buf, "Load Once: %s\n", pa_yes_no(i->load_once));
490 pa_strbuf_puts(buf, "Failed to open module.\n");
495 static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
501 pa_core_assert_ref(c);
506 if (!(n = pa_tokenizer_get(t, 1))) {
507 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
511 if (!(v = pa_tokenizer_get(t, 2))) {
512 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
516 if (pa_atou(v, &volume) < 0) {
517 pa_strbuf_puts(buf, "Failed to parse volume.\n");
521 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
522 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
526 pa_cvolume_set(&cvolume, sink->sample_spec.channels, volume);
527 pa_sink_set_volume(sink, &cvolume, TRUE, TRUE);
531 static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
538 pa_core_assert_ref(c);
543 if (!(n = pa_tokenizer_get(t, 1))) {
544 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
548 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
549 pa_strbuf_puts(buf, "Failed to parse index.\n");
553 if (!(v = pa_tokenizer_get(t, 2))) {
554 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
558 if (pa_atou(v, &volume) < 0) {
559 pa_strbuf_puts(buf, "Failed to parse volume.\n");
563 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
564 pa_strbuf_puts(buf, "No sink input found with this index.\n");
568 pa_cvolume_set(&cvolume, si->sample_spec.channels, volume);
569 pa_sink_input_set_volume(si, &cvolume, TRUE);
573 static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
579 pa_core_assert_ref(c);
584 if (!(n = pa_tokenizer_get(t, 1))) {
585 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
589 if (!(v = pa_tokenizer_get(t, 2))) {
590 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
594 if (pa_atou(v, &volume) < 0) {
595 pa_strbuf_puts(buf, "Failed to parse volume.\n");
599 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
600 pa_strbuf_puts(buf, "No source found by this name or index.\n");
604 pa_cvolume_set(&cvolume, source->sample_spec.channels, volume);
605 pa_source_set_volume(source, &cvolume);
609 static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
614 pa_core_assert_ref(c);
619 if (!(n = pa_tokenizer_get(t, 1))) {
620 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
624 if (!(m = pa_tokenizer_get(t, 2))) {
625 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
629 if ((mute = pa_parse_boolean(m)) < 0) {
630 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
634 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
635 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
639 pa_sink_set_mute(sink, mute);
643 static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
648 pa_core_assert_ref(c);
653 if (!(n = pa_tokenizer_get(t, 1))) {
654 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
658 if (!(m = pa_tokenizer_get(t, 2))) {
659 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
663 if ((mute = pa_parse_boolean(m)) < 0) {
664 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
668 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
669 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
673 pa_source_set_mute(source, mute);
677 static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
682 pa_core_assert_ref(c);
687 if (!(n = pa_tokenizer_get(t, 1))) {
688 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
692 if (!(s = pa_tokenizer_get(t, 2))) {
693 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
697 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
698 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
702 if (!(p = pa_proplist_from_string(s))) {
703 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
707 pa_sink_update_proplist(sink, PA_UPDATE_REPLACE, p);
714 static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
719 pa_core_assert_ref(c);
724 if (!(n = pa_tokenizer_get(t, 1))) {
725 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
729 if (!(s = pa_tokenizer_get(t, 2))) {
730 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
734 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
735 pa_strbuf_puts(buf, "No source found by this name or index.\n");
739 if (!(p = pa_proplist_from_string(s))) {
740 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
744 pa_source_update_proplist(source, PA_UPDATE_REPLACE, p);
751 static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
757 pa_core_assert_ref(c);
762 if (!(n = pa_tokenizer_get(t, 1))) {
763 pa_strbuf_puts(buf, "You need to specify a sink input either by index.\n");
767 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
768 pa_strbuf_puts(buf, "Failed to parse index.\n");
772 if (!(s = pa_tokenizer_get(t, 2))) {
773 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
777 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
778 pa_strbuf_puts(buf, "No sink input found with this index.\n");
782 if (!(p = pa_proplist_from_string(s))) {
783 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
787 pa_sink_input_update_proplist(si, PA_UPDATE_REPLACE, p);
794 static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
796 pa_source_output *so;
800 pa_core_assert_ref(c);
805 if (!(n = pa_tokenizer_get(t, 1))) {
806 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
810 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
811 pa_strbuf_puts(buf, "Failed to parse index.\n");
815 if (!(s = pa_tokenizer_get(t, 2))) {
816 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
820 if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
821 pa_strbuf_puts(buf, "No source output found with this index.\n");
825 if (!(p = pa_proplist_from_string(s))) {
826 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
830 pa_source_output_update_proplist(so, PA_UPDATE_REPLACE, p);
837 static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
843 pa_core_assert_ref(c);
848 if (!(n = pa_tokenizer_get(t, 1))) {
849 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
853 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
854 pa_strbuf_puts(buf, "Failed to parse index.\n");
858 if (!(v = pa_tokenizer_get(t, 2))) {
859 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
863 if ((mute = pa_parse_boolean(v)) < 0) {
864 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
868 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
869 pa_strbuf_puts(buf, "No sink input found with this index.\n");
873 pa_sink_input_set_mute(si, mute, TRUE);
877 static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
881 pa_core_assert_ref(c);
886 if (!(n = pa_tokenizer_get(t, 1))) {
887 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
891 if ((s = pa_namereg_get(c, n, PA_NAMEREG_SINK)))
892 pa_namereg_set_default_sink(c, s);
894 pa_strbuf_printf(buf, "Sink %s does not exist.\n", n);
899 static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
903 pa_core_assert_ref(c);
908 if (!(n = pa_tokenizer_get(t, 1))) {
909 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
913 if ((s = pa_namereg_get(c, n, PA_NAMEREG_SOURCE)))
914 pa_namereg_set_default_source(c, s);
916 pa_strbuf_printf(buf, "Source %s does not exist.\n", n);
920 static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
925 pa_core_assert_ref(c);
930 if (!(n = pa_tokenizer_get(t, 1))) {
931 pa_strbuf_puts(buf, "You need to specify a client by its index.\n");
935 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
936 pa_strbuf_puts(buf, "Failed to parse index.\n");
940 if (!(client = pa_idxset_get_by_index(c->clients, idx))) {
941 pa_strbuf_puts(buf, "No client found by this index.\n");
945 pa_client_kill(client);
949 static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
951 pa_sink_input *sink_input;
954 pa_core_assert_ref(c);
959 if (!(n = pa_tokenizer_get(t, 1))) {
960 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
964 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
965 pa_strbuf_puts(buf, "Failed to parse index.\n");
969 if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) {
970 pa_strbuf_puts(buf, "No sink input found by this index.\n");
974 pa_sink_input_kill(sink_input);
978 static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
980 pa_source_output *source_output;
983 pa_core_assert_ref(c);
988 if (!(n = pa_tokenizer_get(t, 1))) {
989 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
993 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
994 pa_strbuf_puts(buf, "Failed to parse index.\n");
998 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) {
999 pa_strbuf_puts(buf, "No source output found by this index.\n");
1003 pa_source_output_kill(source_output);
1007 static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1010 pa_core_assert_ref(c);
1015 pa_assert_se(s = pa_scache_list_to_string(c));
1016 pa_strbuf_puts(buf, s);
1022 static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1023 const char *n, *sink_name;
1027 pa_core_assert_ref(c);
1032 if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
1033 pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n");
1037 if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
1038 pa_strbuf_puts(buf, "No sink by that name.\n");
1042 if (pa_scache_play_item(c, n, sink, PA_VOLUME_NORM, NULL, &idx) < 0) {
1043 pa_strbuf_puts(buf, "Failed to play sample.\n");
1047 pa_strbuf_printf(buf, "Playing on sink input #%i\n", idx);
1052 static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1055 pa_core_assert_ref(c);
1060 if (!(n = pa_tokenizer_get(t, 1))) {
1061 pa_strbuf_puts(buf, "You need to specify a sample name.\n");
1065 if (pa_scache_remove_item(c, n) < 0) {
1066 pa_strbuf_puts(buf, "Failed to remove sample.\n");
1073 static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1074 const char *fname, *n;
1077 pa_core_assert_ref(c);
1082 if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) {
1083 pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n");
1087 if (strstr(pa_tokenizer_get(t, 0), "lazy"))
1088 r = pa_scache_add_file_lazy(c, n, fname, NULL);
1090 r = pa_scache_add_file(c, n, fname, NULL);
1093 pa_strbuf_puts(buf, "Failed to load sound file.\n");
1098 static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1101 pa_core_assert_ref(c);
1106 if (!(pname = pa_tokenizer_get(t, 1))) {
1107 pa_strbuf_puts(buf, "You need to specify a path name.\n");
1111 if (pa_scache_add_directory_lazy(c, pname) < 0) {
1112 pa_strbuf_puts(buf, "Failed to load directory.\n");
1119 static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1120 const char *fname, *sink_name;
1123 pa_core_assert_ref(c);
1128 if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
1129 pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n");
1133 if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
1134 pa_strbuf_puts(buf, "No sink by that name.\n");
1139 return pa_play_file(sink, fname, NULL);
1142 static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1143 pa_core_assert_ref(c);
1148 pa_shared_dump(c, buf);
1152 static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1153 pa_core_assert_ref(c);
1158 pa_mempool_vacuum(c->mempool);
1163 static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1169 pa_core_assert_ref(c);
1174 if (!(n = pa_tokenizer_get(t, 1))) {
1175 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
1179 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
1180 pa_strbuf_puts(buf, "Failed to parse index.\n");
1184 if (!(k = pa_tokenizer_get(t, 2))) {
1185 pa_strbuf_puts(buf, "You need to specify a sink.\n");
1189 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
1190 pa_strbuf_puts(buf, "No sink input found with this index.\n");
1194 if (!(sink = pa_namereg_get(c, k, PA_NAMEREG_SINK))) {
1195 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
1199 if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
1200 pa_strbuf_puts(buf, "Moved failed.\n");
1206 static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1208 pa_source_output *so;
1212 pa_core_assert_ref(c);
1217 if (!(n = pa_tokenizer_get(t, 1))) {
1218 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
1222 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
1223 pa_strbuf_puts(buf, "Failed to parse index.\n");
1227 if (!(k = pa_tokenizer_get(t, 2))) {
1228 pa_strbuf_puts(buf, "You need to specify a source.\n");
1232 if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
1233 pa_strbuf_puts(buf, "No source output found with this index.\n");
1237 if (!(source = pa_namereg_get(c, k, PA_NAMEREG_SOURCE))) {
1238 pa_strbuf_puts(buf, "No source found by this name or index.\n");
1242 if (pa_source_output_move_to(so, source, TRUE) < 0) {
1243 pa_strbuf_puts(buf, "Moved failed.\n");
1249 static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1254 pa_core_assert_ref(c);
1259 if (!(n = pa_tokenizer_get(t, 1))) {
1260 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
1264 if (!(m = pa_tokenizer_get(t, 2))) {
1265 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1269 if ((suspend = pa_parse_boolean(m)) < 0) {
1270 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1274 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
1275 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
1279 if ((r = pa_sink_suspend(sink, suspend)) < 0)
1280 pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r));
1285 static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1290 pa_core_assert_ref(c);
1295 if (!(n = pa_tokenizer_get(t, 1))) {
1296 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
1300 if (!(m = pa_tokenizer_get(t, 2))) {
1301 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1305 if ((suspend = pa_parse_boolean(m)) < 0) {
1306 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1310 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
1311 pa_strbuf_puts(buf, "No source found by this name or index.\n");
1315 if ((r = pa_source_suspend(source, suspend)) < 0)
1316 pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r));
1321 static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1325 pa_core_assert_ref(c);
1330 if (!(m = pa_tokenizer_get(t, 1))) {
1331 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1335 if ((suspend = pa_parse_boolean(m)) < 0) {
1336 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1340 if ((r = pa_sink_suspend_all(c, suspend)) < 0)
1341 pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r));
1343 if ((r = pa_source_suspend_all(c, suspend)) < 0)
1344 pa_strbuf_printf(buf, "Failed to resume/suspend all sources: %s\n", pa_strerror(r));
1349 static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1353 pa_core_assert_ref(c);
1358 if (!(m = pa_tokenizer_get(t, 1))) {
1359 pa_strbuf_puts(buf, "You need to specify a log level (0..4).\n");
1363 if (pa_atou(m, &level) < 0 || level >= PA_LOG_LEVEL_MAX) {
1364 pa_strbuf_puts(buf, "Failed to parse log level.\n");
1368 pa_log_set_level(level);
1373 static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1377 pa_core_assert_ref(c);
1382 if (!(m = pa_tokenizer_get(t, 1))) {
1383 pa_strbuf_puts(buf, "You need to specify a boolean.\n");
1387 if ((b = pa_parse_boolean(m)) < 0) {
1388 pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
1392 pa_log_set_flags(PA_LOG_PRINT_META, b ? PA_LOG_SET : PA_LOG_UNSET);
1397 static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1401 pa_core_assert_ref(c);
1406 if (!(m = pa_tokenizer_get(t, 1))) {
1407 pa_strbuf_puts(buf, "You need to specify a boolean.\n");
1411 if ((b = pa_parse_boolean(m)) < 0) {
1412 pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
1416 pa_log_set_flags(PA_LOG_PRINT_TIME, b ? PA_LOG_SET : PA_LOG_UNSET);
1421 static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1425 pa_core_assert_ref(c);
1430 if (!(m = pa_tokenizer_get(t, 1))) {
1431 pa_strbuf_puts(buf, "You need to specify a backtrace level.\n");
1435 if (pa_atou(m, &nframes) < 0 || nframes >= 1000) {
1436 pa_strbuf_puts(buf, "Failed to parse backtrace level.\n");
1440 pa_log_set_show_backtrace(nframes);
1445 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1449 pa_core_assert_ref(c);
1454 if (!(n = pa_tokenizer_get(t, 1))) {
1455 pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
1459 if (!(p = pa_tokenizer_get(t, 2))) {
1460 pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
1464 if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
1465 pa_strbuf_puts(buf, "No card found by this name or index.\n");
1469 if (pa_card_set_profile(card, p, TRUE) < 0) {
1470 pa_strbuf_printf(buf, "Failed to set card profile to '%s'.\n", p);
1477 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1487 pa_core_assert_ref(c);
1495 pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt));
1497 pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now));
1500 for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) {
1502 pa_strbuf_printf(buf, "load-module %s", m->name);
1505 pa_strbuf_printf(buf, " %s", m->argument);
1507 pa_strbuf_puts(buf, "\n");
1512 for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
1515 pa_strbuf_puts(buf, "\n");
1519 pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)));
1520 pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
1521 pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
1524 for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
1527 pa_strbuf_puts(buf, "\n");
1531 pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, FALSE)));
1532 pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
1533 pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
1536 for (card = pa_idxset_first(c->cards, &idx); card; card = pa_idxset_next(c->cards, &idx)) {
1539 pa_strbuf_puts(buf, "\n");
1543 if (card->active_profile)
1544 pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
1549 if ((sink = pa_namereg_get_default_sink(c))) {
1551 pa_strbuf_puts(buf, "\n");
1554 pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name);
1557 if ((source = pa_namereg_get_default_source(c))) {
1559 pa_strbuf_puts(buf, "\n");
1562 pa_strbuf_printf(buf, "set-default-source %s\n", source->name);
1565 pa_strbuf_puts(buf, "\n### EOF\n");
1570 int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail, int *ifstate) {
1577 cs = s+strspn(s, whitespace);
1579 if (*cs == '#' || !*cs)
1581 else if (*cs == '.') {
1582 if (!strcmp(cs, META_ELSE)) {
1583 if (!ifstate || *ifstate == IFSTATE_NONE) {
1584 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1586 } else if (*ifstate == IFSTATE_TRUE)
1587 *ifstate = IFSTATE_FALSE;
1589 *ifstate = IFSTATE_TRUE;
1591 } else if (!strcmp(cs, META_ENDIF)) {
1592 if (!ifstate || *ifstate == IFSTATE_NONE) {
1593 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1596 *ifstate = IFSTATE_NONE;
1599 if (ifstate && *ifstate == IFSTATE_FALSE)
1601 if (!strcmp(cs, META_FAIL))
1603 else if (!strcmp(cs, META_NOFAIL))
1607 l = strcspn(cs, whitespace);
1609 if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) {
1610 const char *filename = cs+l+strspn(cs+l, whitespace);
1611 if (pa_cli_command_execute_file(c, filename, buf, fail) < 0)
1614 } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) {
1616 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1618 } else if (*ifstate != IFSTATE_NONE) {
1619 pa_strbuf_printf(buf, "Nested %s commands not supported\n", cs);
1622 const char *filename = cs+l+strspn(cs+l, whitespace);
1624 /* Search DL_SEARCH_PATH unless the filename is absolute */
1625 if (filename[0] == PA_PATH_SEP_CHAR) {
1627 *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
1628 pa_log_debug("Checking for existance of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure");
1631 const char *paths, *state = NULL;
1634 if (!(paths = lt_dlgetsearchpath()))
1637 while ((p = pa_split(paths, ":", &state))) {
1640 pathname = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", p, filename);
1643 *ifstate = access(pathname, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
1644 pa_log_debug("Checking for existance of '%s': %s", pathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
1648 if (*ifstate == IFSTATE_TRUE)
1655 pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs);
1656 if (*fail) return -1;
1660 const struct command*command;
1664 if (ifstate && *ifstate == IFSTATE_FALSE)
1667 l = strcspn(cs, whitespace);
1669 for (command = commands; command->name; command++)
1670 if (strlen(command->name) == l && !strncmp(cs, command->name, l)) {
1672 pa_tokenizer *t = pa_tokenizer_new(cs, command->args);
1674 ret = command->proc(c, t, buf, fail);
1675 pa_tokenizer_free(t);
1678 if (ret < 0 && *fail)
1685 pa_strbuf_printf(buf, "Unknown command: %s\n", cs);
1694 int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
1695 return pa_cli_command_execute_line_stateful(c, s, buf, fail, NULL);
1698 int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) {
1700 int ifstate = IFSTATE_NONE;
1702 pa_bool_t _fail = TRUE;
1711 while (fgets(line, sizeof(line), f)) {
1714 if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail)
1725 int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_bool_t *fail) {
1728 pa_bool_t _fail = TRUE;
1737 if (!(f = fopen(fn, "r"))) {
1738 pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
1744 ret = pa_cli_command_execute_file_stream(c, f, buf, fail);
1755 int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
1757 int ifstate = IFSTATE_NONE;
1758 pa_bool_t _fail = TRUE;
1769 size_t l = strcspn(p, linebreak);
1770 char *line = pa_xstrndup(p, l);
1772 if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail) {
1779 p += strspn(p, linebreak);