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);
128 static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
129 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
131 /* A method table for all available commands */
133 static const struct command commands[] = {
134 { "exit", pa_cli_command_exit, "Terminate the daemon", 1 },
135 { "help", pa_cli_command_help, "Show this help", 1 },
136 { "list-modules", pa_cli_command_modules, "List loaded modules", 1 },
137 { "list-sinks", pa_cli_command_sinks, "List loaded sinks", 1 },
138 { "list-sources", pa_cli_command_sources, "List loaded sources", 1 },
139 { "list-clients", pa_cli_command_clients, "List loaded clients", 1 },
140 { "list-sink-inputs", pa_cli_command_sink_inputs, "List sink inputs", 1 },
141 { "list-source-outputs", pa_cli_command_source_outputs, "List source outputs", 1 },
142 { "list-cards", pa_cli_command_cards, "List cards", 1 },
143 { "stat", pa_cli_command_stat, "Show memory block statistics", 1 },
144 { "info", pa_cli_command_info, "Show comprehensive status", 1 },
145 { "ls", pa_cli_command_info, NULL, 1 },
146 { "list", pa_cli_command_info, NULL, 1 },
147 { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3},
148 { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2},
149 { "describe-module", pa_cli_command_describe, "Describe a module (arg: name)", 2},
150 { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3},
151 { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index, volume)", 3},
152 { "set-source-volume", pa_cli_command_source_volume, "Set the volume of a source (args: index|name, volume)", 3},
153 { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, bool)", 3},
154 { "set-sink-input-mute", pa_cli_command_sink_input_mute, "Set the mute switch of a sink input (args: index, bool)", 3},
155 { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, bool)", 3},
156 { "update-sink-proplist", pa_cli_command_update_sink_proplist, "Update the properties of a sink (args: index|name, properties)", 3},
157 { "update-source-proplist", pa_cli_command_update_source_proplist, "Update the properties of a source (args: index|name, properties)", 3},
158 { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist, "Update the properties of a sink input (args: index, properties)", 3},
159 { "update-source-output-proplist", pa_cli_command_update_source_output_proplist, "Update the properties of a source_output (args: index, properties)", 3},
160 { "set-default-sink", pa_cli_command_sink_default, "Set the default sink (args: index|name)", 2},
161 { "set-default-source", pa_cli_command_source_default, "Set the default source (args: index|name)", 2},
162 { "kill-client", pa_cli_command_kill_client, "Kill a client (args: index)", 2},
163 { "kill-sink-input", pa_cli_command_kill_sink_input, "Kill a sink input (args: index)", 2},
164 { "kill-source-output", pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2},
165 { "list-samples", pa_cli_command_scache_list, "List all entries in the sample cache", 1},
166 { "play-sample", pa_cli_command_scache_play, "Play a sample from the sample cache (args: name, sink|index)", 3},
167 { "remove-sample", pa_cli_command_scache_remove, "Remove a sample from the sample cache (args: name)", 2},
168 { "load-sample", pa_cli_command_scache_load, "Load a sound file into the sample cache (args: name, filename)", 3},
169 { "load-sample-lazy", pa_cli_command_scache_load, "Lazily load a sound file into the sample cache (args: name, filename)", 3},
170 { "load-sample-dir-lazy", pa_cli_command_scache_load_dir, "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
171 { "play-file", pa_cli_command_play_file, "Play a sound file (args: filename, sink|index)", 3},
172 { "dump", pa_cli_command_dump, "Dump daemon configuration", 1},
173 { "shared", pa_cli_command_list_shared_props, NULL, 1},
174 { "move-sink-input", pa_cli_command_move_sink_input, "Move sink input to another sink (args: index, sink)", 3},
175 { "move-source-output", pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3},
176 { "vacuum", pa_cli_command_vacuum, NULL, 1},
177 { "suspend-sink", pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3},
178 { "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3},
179 { "suspend", pa_cli_command_suspend, "Suspend all sinks and all sources (args: bool)", 2},
180 { "set-card-profile", pa_cli_command_card_profile, "Change the profile of a card (args: index, name)", 3},
181 { "set-sink-port", pa_cli_command_sink_port, "Change the port of a sink (args: index, name)", 3},
182 { "set-source-port", pa_cli_command_source_port, "Change the port of a source (args: index, name)", 3},
183 { "set-log-level", pa_cli_command_log_level, "Change the log level (args: numeric level)", 2},
184 { "set-log-meta", pa_cli_command_log_meta, "Show source code location in log messages (args: bool)", 2},
185 { "set-log-time", pa_cli_command_log_time, "Show timestamps in log messages (args: bool)", 2},
186 { "set-log-backtrace", pa_cli_command_log_backtrace, "Show backtrace in log messages (args: frames)", 2},
187 { NULL, NULL, NULL, 0 }
190 static const char whitespace[] = " \t\n\r";
191 static const char linebreak[] = "\n\r";
193 static uint32_t parse_index(const char *n) {
196 if (pa_atou(n, &idx) < 0)
197 return (uint32_t) PA_IDXSET_INVALID;
202 static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
203 pa_core_assert_ref(c);
208 if (pa_core_exit(c, FALSE, 0) < 0)
209 pa_strbuf_puts(buf, "Not allowed to terminate daemon.\n");
214 static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
215 const struct command*command;
217 pa_core_assert_ref(c);
222 pa_strbuf_puts(buf, "Available commands:\n");
224 for (command = commands; command->name; command++)
226 pa_strbuf_printf(buf, " %-25s %s\n", command->name, command->help);
230 static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
233 pa_core_assert_ref(c);
238 pa_assert_se(s = pa_module_list_to_string(c));
239 pa_strbuf_puts(buf, s);
244 static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
247 pa_core_assert_ref(c);
252 pa_assert_se(s = pa_client_list_to_string(c));
253 pa_strbuf_puts(buf, s);
258 static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
261 pa_core_assert_ref(c);
266 pa_assert_se(s = pa_card_list_to_string(c));
267 pa_strbuf_puts(buf, s);
272 static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
275 pa_core_assert_ref(c);
280 pa_assert_se(s = pa_sink_list_to_string(c));
281 pa_strbuf_puts(buf, s);
286 static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
289 pa_core_assert_ref(c);
294 pa_assert_se(s = pa_source_list_to_string(c));
295 pa_strbuf_puts(buf, s);
300 static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
303 pa_core_assert_ref(c);
308 pa_assert_se(s = pa_sink_input_list_to_string(c));
309 pa_strbuf_puts(buf, s);
314 static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
317 pa_core_assert_ref(c);
322 pa_assert_se(s = pa_source_output_list_to_string(c));
323 pa_strbuf_puts(buf, s);
328 static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
329 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
330 char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
331 char bytes[PA_BYTES_SNPRINT_MAX];
332 const pa_mempool_stat *stat;
335 pa_source *def_source;
337 static const char* const type_table[PA_MEMBLOCK_TYPE_MAX] = {
338 [PA_MEMBLOCK_POOL] = "POOL",
339 [PA_MEMBLOCK_POOL_EXTERNAL] = "POOL_EXTERNAL",
340 [PA_MEMBLOCK_APPENDED] = "APPENDED",
341 [PA_MEMBLOCK_USER] = "USER",
342 [PA_MEMBLOCK_FIXED] = "FIXED",
343 [PA_MEMBLOCK_IMPORTED] = "IMPORTED",
346 pa_core_assert_ref(c);
351 stat = pa_mempool_get_stat(c->mempool);
353 pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
354 (unsigned) pa_atomic_load(&stat->n_allocated),
355 pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->allocated_size)));
357 pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
358 (unsigned) pa_atomic_load(&stat->n_accumulated),
359 pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->accumulated_size)));
361 pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
362 (unsigned) pa_atomic_load(&stat->n_imported),
363 pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->imported_size)));
365 pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
366 (unsigned) pa_atomic_load(&stat->n_exported),
367 pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->exported_size)));
369 pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
370 pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c)));
372 pa_strbuf_printf(buf, "Default sample spec: %s\n",
373 pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec));
375 pa_strbuf_printf(buf, "Default channel map: %s\n",
376 pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
378 def_sink = pa_namereg_get_default_sink(c);
379 def_source = pa_namereg_get_default_source(c);
380 pa_strbuf_printf(buf, "Default sink name: %s\n"
381 "Default source name: %s\n",
382 def_sink ? def_sink->name : "none",
383 def_source ? def_source->name : "none");
385 for (k = 0; k < PA_MEMBLOCK_TYPE_MAX; k++)
386 pa_strbuf_printf(buf,
387 "Memory blocks of type %s: %u allocated/%u accumulated.\n",
389 (unsigned) pa_atomic_load(&stat->n_allocated_by_type[k]),
390 (unsigned) pa_atomic_load(&stat->n_accumulated_by_type[k]));
395 static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
396 pa_core_assert_ref(c);
401 pa_cli_command_stat(c, t, buf, fail);
402 pa_cli_command_modules(c, t, buf, fail);
403 pa_cli_command_sinks(c, t, buf, fail);
404 pa_cli_command_sources(c, t, buf, fail);
405 pa_cli_command_clients(c, t, buf, fail);
406 pa_cli_command_cards(c, t, buf, fail);
407 pa_cli_command_sink_inputs(c, t, buf, fail);
408 pa_cli_command_source_outputs(c, t, buf, fail);
409 pa_cli_command_scache_list(c, t, buf, fail);
413 static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
416 pa_core_assert_ref(c);
421 if (!(name = pa_tokenizer_get(t, 1))) {
422 pa_strbuf_puts(buf, "You need to specify the module name and optionally arguments.\n");
426 if (!pa_module_load(c, name, pa_tokenizer_get(t, 2))) {
427 pa_strbuf_puts(buf, "Module load failed.\n");
434 static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
440 pa_core_assert_ref(c);
445 if (!(i = pa_tokenizer_get(t, 1))) {
446 pa_strbuf_puts(buf, "You need to specify the module index.\n");
450 idx = (uint32_t) strtoul(i, &e, 10);
451 if (*e || !(m = pa_idxset_get_by_index(c->modules, idx))) {
452 pa_strbuf_puts(buf, "Invalid module index.\n");
456 pa_module_unload_request(m, FALSE);
460 static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
464 pa_core_assert_ref(c);
469 if (!(name = pa_tokenizer_get(t, 1))) {
470 pa_strbuf_puts(buf, "You need to specify the module name.\n");
474 if ((i = pa_modinfo_get_by_name(name))) {
476 pa_strbuf_printf(buf, "Name: %s\n", name);
478 if (!i->description && !i->version && !i->author && !i->usage)
479 pa_strbuf_printf(buf, "No module information available\n");
482 pa_strbuf_printf(buf, "Version: %s\n", i->version);
484 pa_strbuf_printf(buf, "Description: %s\n", i->description);
486 pa_strbuf_printf(buf, "Author: %s\n", i->author);
488 pa_strbuf_printf(buf, "Usage: %s\n", i->usage);
489 pa_strbuf_printf(buf, "Load Once: %s\n", pa_yes_no(i->load_once));
491 pa_strbuf_printf(buf, "Warning, deprecated: %s\n", i->deprecated);
496 pa_strbuf_puts(buf, "Failed to open module.\n");
501 static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
507 pa_core_assert_ref(c);
512 if (!(n = pa_tokenizer_get(t, 1))) {
513 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
517 if (!(v = pa_tokenizer_get(t, 2))) {
518 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
522 if (pa_atou(v, &volume) < 0) {
523 pa_strbuf_puts(buf, "Failed to parse volume.\n");
527 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
528 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
532 pa_cvolume_set(&cvolume, 1, volume);
533 pa_sink_set_volume(sink, &cvolume, TRUE, TRUE);
537 static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
544 pa_core_assert_ref(c);
549 if (!(n = pa_tokenizer_get(t, 1))) {
550 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
554 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
555 pa_strbuf_puts(buf, "Failed to parse index.\n");
559 if (!(v = pa_tokenizer_get(t, 2))) {
560 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
564 if (pa_atou(v, &volume) < 0) {
565 pa_strbuf_puts(buf, "Failed to parse volume.\n");
569 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
570 pa_strbuf_puts(buf, "No sink input found with this index.\n");
574 pa_cvolume_set(&cvolume, 1, volume);
575 pa_sink_input_set_volume(si, &cvolume, TRUE, TRUE);
579 static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
585 pa_core_assert_ref(c);
590 if (!(n = pa_tokenizer_get(t, 1))) {
591 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
595 if (!(v = pa_tokenizer_get(t, 2))) {
596 pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
600 if (pa_atou(v, &volume) < 0) {
601 pa_strbuf_puts(buf, "Failed to parse volume.\n");
605 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
606 pa_strbuf_puts(buf, "No source found by this name or index.\n");
610 pa_cvolume_set(&cvolume, 1, volume);
611 pa_source_set_volume(source, &cvolume, TRUE);
615 static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
620 pa_core_assert_ref(c);
625 if (!(n = pa_tokenizer_get(t, 1))) {
626 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
630 if (!(m = pa_tokenizer_get(t, 2))) {
631 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
635 if ((mute = pa_parse_boolean(m)) < 0) {
636 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
640 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
641 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
645 pa_sink_set_mute(sink, mute, TRUE);
649 static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
654 pa_core_assert_ref(c);
659 if (!(n = pa_tokenizer_get(t, 1))) {
660 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
664 if (!(m = pa_tokenizer_get(t, 2))) {
665 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
669 if ((mute = pa_parse_boolean(m)) < 0) {
670 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
674 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
675 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
679 pa_source_set_mute(source, mute, TRUE);
683 static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
688 pa_core_assert_ref(c);
693 if (!(n = pa_tokenizer_get(t, 1))) {
694 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
698 if (!(s = pa_tokenizer_get(t, 2))) {
699 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
703 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
704 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
708 if (!(p = pa_proplist_from_string(s))) {
709 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
713 pa_sink_update_proplist(sink, PA_UPDATE_REPLACE, p);
720 static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
725 pa_core_assert_ref(c);
730 if (!(n = pa_tokenizer_get(t, 1))) {
731 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
735 if (!(s = pa_tokenizer_get(t, 2))) {
736 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
740 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
741 pa_strbuf_puts(buf, "No source found by this name or index.\n");
745 if (!(p = pa_proplist_from_string(s))) {
746 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
750 pa_source_update_proplist(source, PA_UPDATE_REPLACE, p);
757 static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
763 pa_core_assert_ref(c);
768 if (!(n = pa_tokenizer_get(t, 1))) {
769 pa_strbuf_puts(buf, "You need to specify a sink input either by index.\n");
773 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
774 pa_strbuf_puts(buf, "Failed to parse index.\n");
778 if (!(s = pa_tokenizer_get(t, 2))) {
779 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
783 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
784 pa_strbuf_puts(buf, "No sink input found with this index.\n");
788 if (!(p = pa_proplist_from_string(s))) {
789 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
793 pa_sink_input_update_proplist(si, PA_UPDATE_REPLACE, p);
800 static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
802 pa_source_output *so;
806 pa_core_assert_ref(c);
811 if (!(n = pa_tokenizer_get(t, 1))) {
812 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
816 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
817 pa_strbuf_puts(buf, "Failed to parse index.\n");
821 if (!(s = pa_tokenizer_get(t, 2))) {
822 pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
826 if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
827 pa_strbuf_puts(buf, "No source output found with this index.\n");
831 if (!(p = pa_proplist_from_string(s))) {
832 pa_strbuf_puts(buf, "Failed to parse proplist.\n");
836 pa_source_output_update_proplist(so, PA_UPDATE_REPLACE, p);
843 static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
849 pa_core_assert_ref(c);
854 if (!(n = pa_tokenizer_get(t, 1))) {
855 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
859 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
860 pa_strbuf_puts(buf, "Failed to parse index.\n");
864 if (!(v = pa_tokenizer_get(t, 2))) {
865 pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
869 if ((mute = pa_parse_boolean(v)) < 0) {
870 pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
874 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
875 pa_strbuf_puts(buf, "No sink input found with this index.\n");
879 pa_sink_input_set_mute(si, mute, TRUE);
883 static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
887 pa_core_assert_ref(c);
892 if (!(n = pa_tokenizer_get(t, 1))) {
893 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
897 if ((s = pa_namereg_get(c, n, PA_NAMEREG_SINK)))
898 pa_namereg_set_default_sink(c, s);
900 pa_strbuf_printf(buf, "Sink %s does not exist.\n", n);
905 static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
909 pa_core_assert_ref(c);
914 if (!(n = pa_tokenizer_get(t, 1))) {
915 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
919 if ((s = pa_namereg_get(c, n, PA_NAMEREG_SOURCE)))
920 pa_namereg_set_default_source(c, s);
922 pa_strbuf_printf(buf, "Source %s does not exist.\n", n);
926 static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
931 pa_core_assert_ref(c);
936 if (!(n = pa_tokenizer_get(t, 1))) {
937 pa_strbuf_puts(buf, "You need to specify a client by its index.\n");
941 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
942 pa_strbuf_puts(buf, "Failed to parse index.\n");
946 if (!(client = pa_idxset_get_by_index(c->clients, idx))) {
947 pa_strbuf_puts(buf, "No client found by this index.\n");
951 pa_client_kill(client);
955 static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
957 pa_sink_input *sink_input;
960 pa_core_assert_ref(c);
965 if (!(n = pa_tokenizer_get(t, 1))) {
966 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
970 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
971 pa_strbuf_puts(buf, "Failed to parse index.\n");
975 if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) {
976 pa_strbuf_puts(buf, "No sink input found by this index.\n");
980 pa_sink_input_kill(sink_input);
984 static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
986 pa_source_output *source_output;
989 pa_core_assert_ref(c);
994 if (!(n = pa_tokenizer_get(t, 1))) {
995 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
999 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
1000 pa_strbuf_puts(buf, "Failed to parse index.\n");
1004 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) {
1005 pa_strbuf_puts(buf, "No source output found by this index.\n");
1009 pa_source_output_kill(source_output);
1013 static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1016 pa_core_assert_ref(c);
1021 pa_assert_se(s = pa_scache_list_to_string(c));
1022 pa_strbuf_puts(buf, s);
1028 static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1029 const char *n, *sink_name;
1033 pa_core_assert_ref(c);
1038 if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
1039 pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n");
1043 if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
1044 pa_strbuf_puts(buf, "No sink by that name.\n");
1048 if (pa_scache_play_item(c, n, sink, PA_VOLUME_NORM, NULL, &idx) < 0) {
1049 pa_strbuf_puts(buf, "Failed to play sample.\n");
1053 pa_strbuf_printf(buf, "Playing on sink input #%i\n", idx);
1058 static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1061 pa_core_assert_ref(c);
1066 if (!(n = pa_tokenizer_get(t, 1))) {
1067 pa_strbuf_puts(buf, "You need to specify a sample name.\n");
1071 if (pa_scache_remove_item(c, n) < 0) {
1072 pa_strbuf_puts(buf, "Failed to remove sample.\n");
1079 static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1080 const char *fname, *n;
1083 pa_core_assert_ref(c);
1088 if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) {
1089 pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n");
1093 if (strstr(pa_tokenizer_get(t, 0), "lazy"))
1094 r = pa_scache_add_file_lazy(c, n, fname, NULL);
1096 r = pa_scache_add_file(c, n, fname, NULL);
1099 pa_strbuf_puts(buf, "Failed to load sound file.\n");
1104 static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1107 pa_core_assert_ref(c);
1112 if (!(pname = pa_tokenizer_get(t, 1))) {
1113 pa_strbuf_puts(buf, "You need to specify a path name.\n");
1117 if (pa_scache_add_directory_lazy(c, pname) < 0) {
1118 pa_strbuf_puts(buf, "Failed to load directory.\n");
1125 static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1126 const char *fname, *sink_name;
1129 pa_core_assert_ref(c);
1134 if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
1135 pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n");
1139 if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
1140 pa_strbuf_puts(buf, "No sink by that name.\n");
1145 return pa_play_file(sink, fname, NULL);
1148 static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1149 pa_core_assert_ref(c);
1154 pa_shared_dump(c, buf);
1158 static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1159 pa_core_assert_ref(c);
1164 pa_mempool_vacuum(c->mempool);
1169 static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1175 pa_core_assert_ref(c);
1180 if (!(n = pa_tokenizer_get(t, 1))) {
1181 pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
1185 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
1186 pa_strbuf_puts(buf, "Failed to parse index.\n");
1190 if (!(k = pa_tokenizer_get(t, 2))) {
1191 pa_strbuf_puts(buf, "You need to specify a sink.\n");
1195 if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
1196 pa_strbuf_puts(buf, "No sink input found with this index.\n");
1200 if (!(sink = pa_namereg_get(c, k, PA_NAMEREG_SINK))) {
1201 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
1205 if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
1206 pa_strbuf_puts(buf, "Moved failed.\n");
1212 static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1214 pa_source_output *so;
1218 pa_core_assert_ref(c);
1223 if (!(n = pa_tokenizer_get(t, 1))) {
1224 pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
1228 if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
1229 pa_strbuf_puts(buf, "Failed to parse index.\n");
1233 if (!(k = pa_tokenizer_get(t, 2))) {
1234 pa_strbuf_puts(buf, "You need to specify a source.\n");
1238 if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
1239 pa_strbuf_puts(buf, "No source output found with this index.\n");
1243 if (!(source = pa_namereg_get(c, k, PA_NAMEREG_SOURCE))) {
1244 pa_strbuf_puts(buf, "No source found by this name or index.\n");
1248 if (pa_source_output_move_to(so, source, TRUE) < 0) {
1249 pa_strbuf_puts(buf, "Moved failed.\n");
1255 static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1260 pa_core_assert_ref(c);
1265 if (!(n = pa_tokenizer_get(t, 1))) {
1266 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
1270 if (!(m = pa_tokenizer_get(t, 2))) {
1271 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1275 if ((suspend = pa_parse_boolean(m)) < 0) {
1276 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1280 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
1281 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
1285 if ((r = pa_sink_suspend(sink, suspend, PA_SUSPEND_USER)) < 0)
1286 pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r));
1291 static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1296 pa_core_assert_ref(c);
1301 if (!(n = pa_tokenizer_get(t, 1))) {
1302 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
1306 if (!(m = pa_tokenizer_get(t, 2))) {
1307 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1311 if ((suspend = pa_parse_boolean(m)) < 0) {
1312 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1316 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
1317 pa_strbuf_puts(buf, "No source found by this name or index.\n");
1321 if ((r = pa_source_suspend(source, suspend, PA_SUSPEND_USER)) < 0)
1322 pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r));
1327 static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1331 pa_core_assert_ref(c);
1336 if (!(m = pa_tokenizer_get(t, 1))) {
1337 pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
1341 if ((suspend = pa_parse_boolean(m)) < 0) {
1342 pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
1346 if ((r = pa_sink_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
1347 pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r));
1349 if ((r = pa_source_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
1350 pa_strbuf_printf(buf, "Failed to resume/suspend all sources: %s\n", pa_strerror(r));
1355 static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1359 pa_core_assert_ref(c);
1364 if (!(m = pa_tokenizer_get(t, 1))) {
1365 pa_strbuf_puts(buf, "You need to specify a log level (0..4).\n");
1369 if (pa_atou(m, &level) < 0 || level >= PA_LOG_LEVEL_MAX) {
1370 pa_strbuf_puts(buf, "Failed to parse log level.\n");
1374 pa_log_set_level(level);
1379 static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1383 pa_core_assert_ref(c);
1388 if (!(m = pa_tokenizer_get(t, 1))) {
1389 pa_strbuf_puts(buf, "You need to specify a boolean.\n");
1393 if ((b = pa_parse_boolean(m)) < 0) {
1394 pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
1398 pa_log_set_flags(PA_LOG_PRINT_META, b ? PA_LOG_SET : PA_LOG_UNSET);
1403 static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1407 pa_core_assert_ref(c);
1412 if (!(m = pa_tokenizer_get(t, 1))) {
1413 pa_strbuf_puts(buf, "You need to specify a boolean.\n");
1417 if ((b = pa_parse_boolean(m)) < 0) {
1418 pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
1422 pa_log_set_flags(PA_LOG_PRINT_TIME, b ? PA_LOG_SET : PA_LOG_UNSET);
1427 static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1431 pa_core_assert_ref(c);
1436 if (!(m = pa_tokenizer_get(t, 1))) {
1437 pa_strbuf_puts(buf, "You need to specify a backtrace level.\n");
1441 if (pa_atou(m, &nframes) < 0 || nframes >= 1000) {
1442 pa_strbuf_puts(buf, "Failed to parse backtrace level.\n");
1446 pa_log_set_show_backtrace(nframes);
1451 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1455 pa_core_assert_ref(c);
1460 if (!(n = pa_tokenizer_get(t, 1))) {
1461 pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
1465 if (!(p = pa_tokenizer_get(t, 2))) {
1466 pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
1470 if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
1471 pa_strbuf_puts(buf, "No card found by this name or index.\n");
1475 if (pa_card_set_profile(card, p, TRUE) < 0) {
1476 pa_strbuf_printf(buf, "Failed to set card profile to '%s'.\n", p);
1483 static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1487 pa_core_assert_ref(c);
1492 if (!(n = pa_tokenizer_get(t, 1))) {
1493 pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
1497 if (!(p = pa_tokenizer_get(t, 2))) {
1498 pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
1502 if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
1503 pa_strbuf_puts(buf, "No sink found by this name or index.\n");
1507 if (pa_sink_set_port(sink, p, TRUE) < 0) {
1508 pa_strbuf_printf(buf, "Failed to set sink port to '%s'.\n", p);
1515 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1519 pa_core_assert_ref(c);
1524 if (!(n = pa_tokenizer_get(t, 1))) {
1525 pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
1529 if (!(p = pa_tokenizer_get(t, 2))) {
1530 pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
1534 if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
1535 pa_strbuf_puts(buf, "No source found by this name or index.\n");
1539 if (pa_source_set_port(source, p, TRUE) < 0) {
1540 pa_strbuf_printf(buf, "Failed to set source port to '%s'.\n", p);
1547 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
1557 pa_core_assert_ref(c);
1565 pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt));
1567 pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now));
1570 PA_IDXSET_FOREACH(m, c->modules, idx) {
1572 pa_strbuf_printf(buf, "load-module %s", m->name);
1575 pa_strbuf_printf(buf, " %s", m->argument);
1577 pa_strbuf_puts(buf, "\n");
1581 PA_IDXSET_FOREACH(sink, c->sinks, idx) {
1584 pa_strbuf_puts(buf, "\n");
1588 pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_max(pa_sink_get_volume(sink, FALSE)));
1589 pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
1590 pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
1594 PA_IDXSET_FOREACH(source, c->sources, idx) {
1597 pa_strbuf_puts(buf, "\n");
1601 pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_max(pa_source_get_volume(source, FALSE)));
1602 pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
1603 pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
1607 PA_IDXSET_FOREACH(card, c->cards, idx) {
1610 pa_strbuf_puts(buf, "\n");
1614 if (card->active_profile)
1615 pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
1619 if ((sink = pa_namereg_get_default_sink(c))) {
1621 pa_strbuf_puts(buf, "\n");
1625 pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name);
1628 if ((source = pa_namereg_get_default_source(c))) {
1630 pa_strbuf_puts(buf, "\n");
1632 pa_strbuf_printf(buf, "set-default-source %s\n", source->name);
1635 pa_strbuf_puts(buf, "\n### EOF\n");
1640 int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail, int *ifstate) {
1647 cs = s+strspn(s, whitespace);
1649 if (*cs == '#' || !*cs)
1651 else if (*cs == '.') {
1652 if (!strcmp(cs, META_ELSE)) {
1653 if (!ifstate || *ifstate == IFSTATE_NONE) {
1654 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1656 } else if (*ifstate == IFSTATE_TRUE)
1657 *ifstate = IFSTATE_FALSE;
1659 *ifstate = IFSTATE_TRUE;
1661 } else if (!strcmp(cs, META_ENDIF)) {
1662 if (!ifstate || *ifstate == IFSTATE_NONE) {
1663 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1666 *ifstate = IFSTATE_NONE;
1669 if (ifstate && *ifstate == IFSTATE_FALSE)
1671 if (!strcmp(cs, META_FAIL))
1673 else if (!strcmp(cs, META_NOFAIL))
1677 l = strcspn(cs, whitespace);
1679 if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) {
1680 const char *filename = cs+l+strspn(cs+l, whitespace);
1681 if (pa_cli_command_execute_file(c, filename, buf, fail) < 0)
1684 } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) {
1686 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
1688 } else if (*ifstate != IFSTATE_NONE) {
1689 pa_strbuf_printf(buf, "Nested %s commands not supported\n", cs);
1692 const char *filename = cs+l+strspn(cs+l, whitespace);
1694 /* Search DL_SEARCH_PATH unless the filename is absolute */
1695 if (filename[0] == PA_PATH_SEP_CHAR) {
1697 *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
1698 pa_log_debug("Checking for existance of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure");
1701 const char *paths, *state = NULL;
1704 if (!(paths = lt_dlgetsearchpath()))
1707 while ((p = pa_split(paths, ":", &state))) {
1710 pathname = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", p, filename);
1713 *ifstate = access(pathname, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
1714 pa_log_debug("Checking for existance of '%s': %s", pathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
1718 if (*ifstate == IFSTATE_TRUE)
1725 pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs);
1726 if (*fail) return -1;
1730 const struct command*command;
1734 if (ifstate && *ifstate == IFSTATE_FALSE)
1737 l = strcspn(cs, whitespace);
1739 for (command = commands; command->name; command++)
1740 if (strlen(command->name) == l && !strncmp(cs, command->name, l)) {
1742 pa_tokenizer *t = pa_tokenizer_new(cs, command->args);
1744 ret = command->proc(c, t, buf, fail);
1745 pa_tokenizer_free(t);
1748 if (ret < 0 && *fail)
1755 pa_strbuf_printf(buf, "Unknown command: %s\n", cs);
1764 int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
1765 return pa_cli_command_execute_line_stateful(c, s, buf, fail, NULL);
1768 int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) {
1770 int ifstate = IFSTATE_NONE;
1772 pa_bool_t _fail = TRUE;
1781 while (fgets(line, sizeof(line), f)) {
1784 if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail)
1795 int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_bool_t *fail) {
1798 pa_bool_t _fail = TRUE;
1807 if (!(f = pa_fopen_cloexec(fn, "r"))) {
1808 pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
1814 ret = pa_cli_command_execute_file_stream(c, f, buf, fail);
1823 int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
1825 int ifstate = IFSTATE_NONE;
1826 pa_bool_t _fail = TRUE;
1837 size_t l = strcspn(p, linebreak);
1838 char *line = pa_xstrndup(p, l);
1840 if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail) {
1847 p += strspn(p, linebreak);