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 (aargs: 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 p
= pa_proplist_from_string(s
);
704 pa_sink_update_proplist(sink
, PA_UPDATE_REPLACE
, p
);
711 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
716 pa_core_assert_ref(c
);
721 if (!(n
= pa_tokenizer_get(t
, 1))) {
722 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
726 if (!(s
= pa_tokenizer_get(t
, 2))) {
727 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
731 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
732 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
736 p
= pa_proplist_from_string(s
);
738 pa_source_update_proplist(source
, PA_UPDATE_REPLACE
, p
);
745 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
751 pa_core_assert_ref(c
);
756 if (!(n
= pa_tokenizer_get(t
, 1))) {
757 pa_strbuf_puts(buf
, "You need to specify a sink input either by index.\n");
761 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
762 pa_strbuf_puts(buf
, "Failed to parse index.\n");
766 if (!(s
= pa_tokenizer_get(t
, 2))) {
767 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
771 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
772 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
776 p
= pa_proplist_from_string(s
);
778 pa_sink_input_update_proplist(si
, PA_UPDATE_REPLACE
, p
);
785 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
787 pa_source_output
*so
;
791 pa_core_assert_ref(c
);
796 if (!(n
= pa_tokenizer_get(t
, 1))) {
797 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
801 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
802 pa_strbuf_puts(buf
, "Failed to parse index.\n");
806 if (!(s
= pa_tokenizer_get(t
, 2))) {
807 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
811 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
812 pa_strbuf_puts(buf
, "No source output found with this index.\n");
816 p
= pa_proplist_from_string(s
);
818 pa_source_output_update_proplist(so
, PA_UPDATE_REPLACE
, p
);
825 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
831 pa_core_assert_ref(c
);
836 if (!(n
= pa_tokenizer_get(t
, 1))) {
837 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
841 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
842 pa_strbuf_puts(buf
, "Failed to parse index.\n");
846 if (!(v
= pa_tokenizer_get(t
, 2))) {
847 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
851 if ((mute
= pa_parse_boolean(v
)) < 0) {
852 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
856 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
857 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
861 pa_sink_input_set_mute(si
, mute
, TRUE
);
865 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
869 pa_core_assert_ref(c
);
874 if (!(n
= pa_tokenizer_get(t
, 1))) {
875 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
879 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
)))
880 pa_namereg_set_default_sink(c
, s
);
882 pa_strbuf_printf(buf
, "Sink %s does not exist.\n", n
);
887 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
891 pa_core_assert_ref(c
);
896 if (!(n
= pa_tokenizer_get(t
, 1))) {
897 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
901 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
)))
902 pa_namereg_set_default_source(c
, s
);
904 pa_strbuf_printf(buf
, "Source %s does not exist.\n", n
);
908 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
913 pa_core_assert_ref(c
);
918 if (!(n
= pa_tokenizer_get(t
, 1))) {
919 pa_strbuf_puts(buf
, "You need to specify a client by its index.\n");
923 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
924 pa_strbuf_puts(buf
, "Failed to parse index.\n");
928 if (!(client
= pa_idxset_get_by_index(c
->clients
, idx
))) {
929 pa_strbuf_puts(buf
, "No client found by this index.\n");
933 pa_client_kill(client
);
937 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
939 pa_sink_input
*sink_input
;
942 pa_core_assert_ref(c
);
947 if (!(n
= pa_tokenizer_get(t
, 1))) {
948 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
952 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
953 pa_strbuf_puts(buf
, "Failed to parse index.\n");
957 if (!(sink_input
= pa_idxset_get_by_index(c
->sink_inputs
, idx
))) {
958 pa_strbuf_puts(buf
, "No sink input found by this index.\n");
962 pa_sink_input_kill(sink_input
);
966 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
968 pa_source_output
*source_output
;
971 pa_core_assert_ref(c
);
976 if (!(n
= pa_tokenizer_get(t
, 1))) {
977 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
981 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
982 pa_strbuf_puts(buf
, "Failed to parse index.\n");
986 if (!(source_output
= pa_idxset_get_by_index(c
->source_outputs
, idx
))) {
987 pa_strbuf_puts(buf
, "No source output found by this index.\n");
991 pa_source_output_kill(source_output
);
995 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
998 pa_core_assert_ref(c
);
1003 pa_assert_se(s
= pa_scache_list_to_string(c
));
1004 pa_strbuf_puts(buf
, s
);
1010 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1011 const char *n
, *sink_name
;
1015 pa_core_assert_ref(c
);
1020 if (!(n
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1021 pa_strbuf_puts(buf
, "You need to specify a sample name and a sink name.\n");
1025 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1026 pa_strbuf_puts(buf
, "No sink by that name.\n");
1030 if (pa_scache_play_item(c
, n
, sink
, PA_VOLUME_NORM
, NULL
, &idx
) < 0) {
1031 pa_strbuf_puts(buf
, "Failed to play sample.\n");
1035 pa_strbuf_printf(buf
, "Playing on sink input #%i\n", idx
);
1040 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1043 pa_core_assert_ref(c
);
1048 if (!(n
= pa_tokenizer_get(t
, 1))) {
1049 pa_strbuf_puts(buf
, "You need to specify a sample name.\n");
1053 if (pa_scache_remove_item(c
, n
) < 0) {
1054 pa_strbuf_puts(buf
, "Failed to remove sample.\n");
1061 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1062 const char *fname
, *n
;
1065 pa_core_assert_ref(c
);
1070 if (!(fname
= pa_tokenizer_get(t
, 2)) || !(n
= pa_tokenizer_get(t
, 1))) {
1071 pa_strbuf_puts(buf
, "You need to specify a file name and a sample name.\n");
1075 if (strstr(pa_tokenizer_get(t
, 0), "lazy"))
1076 r
= pa_scache_add_file_lazy(c
, n
, fname
, NULL
);
1078 r
= pa_scache_add_file(c
, n
, fname
, NULL
);
1081 pa_strbuf_puts(buf
, "Failed to load sound file.\n");
1086 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1089 pa_core_assert_ref(c
);
1094 if (!(pname
= pa_tokenizer_get(t
, 1))) {
1095 pa_strbuf_puts(buf
, "You need to specify a path name.\n");
1099 if (pa_scache_add_directory_lazy(c
, pname
) < 0) {
1100 pa_strbuf_puts(buf
, "Failed to load directory.\n");
1107 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1108 const char *fname
, *sink_name
;
1111 pa_core_assert_ref(c
);
1116 if (!(fname
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1117 pa_strbuf_puts(buf
, "You need to specify a file name and a sink name.\n");
1121 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1122 pa_strbuf_puts(buf
, "No sink by that name.\n");
1127 return pa_play_file(sink
, fname
, NULL
);
1130 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1131 pa_core_assert_ref(c
);
1136 pa_shared_dump(c
, buf
);
1140 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1141 pa_core_assert_ref(c
);
1146 pa_mempool_vacuum(c
->mempool
);
1151 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1157 pa_core_assert_ref(c
);
1162 if (!(n
= pa_tokenizer_get(t
, 1))) {
1163 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
1167 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1168 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1172 if (!(k
= pa_tokenizer_get(t
, 2))) {
1173 pa_strbuf_puts(buf
, "You need to specify a sink.\n");
1177 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
1178 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
1182 if (!(sink
= pa_namereg_get(c
, k
, PA_NAMEREG_SINK
))) {
1183 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1187 if (pa_sink_input_move_to(si
, sink
, TRUE
) < 0) {
1188 pa_strbuf_puts(buf
, "Moved failed.\n");
1194 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1196 pa_source_output
*so
;
1200 pa_core_assert_ref(c
);
1205 if (!(n
= pa_tokenizer_get(t
, 1))) {
1206 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
1210 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1211 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1215 if (!(k
= pa_tokenizer_get(t
, 2))) {
1216 pa_strbuf_puts(buf
, "You need to specify a source.\n");
1220 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
1221 pa_strbuf_puts(buf
, "No source output found with this index.\n");
1225 if (!(source
= pa_namereg_get(c
, k
, PA_NAMEREG_SOURCE
))) {
1226 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1230 if (pa_source_output_move_to(so
, source
, TRUE
) < 0) {
1231 pa_strbuf_puts(buf
, "Moved failed.\n");
1237 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1242 pa_core_assert_ref(c
);
1247 if (!(n
= pa_tokenizer_get(t
, 1))) {
1248 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1252 if (!(m
= pa_tokenizer_get(t
, 2))) {
1253 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1257 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1258 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1262 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
1263 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1267 if ((r
= pa_sink_suspend(sink
, suspend
)) < 0)
1268 pa_strbuf_printf(buf
, "Failed to resume/suspend sink: %s\n", pa_strerror(r
));
1273 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1278 pa_core_assert_ref(c
);
1283 if (!(n
= pa_tokenizer_get(t
, 1))) {
1284 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1288 if (!(m
= pa_tokenizer_get(t
, 2))) {
1289 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1293 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1294 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1298 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
1299 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1303 if ((r
= pa_source_suspend(source
, suspend
)) < 0)
1304 pa_strbuf_printf(buf
, "Failed to resume/suspend source: %s\n", pa_strerror(r
));
1309 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1313 pa_core_assert_ref(c
);
1318 if (!(m
= pa_tokenizer_get(t
, 1))) {
1319 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1323 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1324 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1328 if ((r
= pa_sink_suspend_all(c
, suspend
)) < 0)
1329 pa_strbuf_printf(buf
, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r
));
1331 if ((r
= pa_source_suspend_all(c
, suspend
)) < 0)
1332 pa_strbuf_printf(buf
, "Failed to resume/suspend all sources: %s\n", pa_strerror(r
));
1337 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1341 pa_core_assert_ref(c
);
1346 if (!(m
= pa_tokenizer_get(t
, 1))) {
1347 pa_strbuf_puts(buf
, "You need to specify a log level (0..4).\n");
1351 if (pa_atou(m
, &level
) < 0 || level
>= PA_LOG_LEVEL_MAX
) {
1352 pa_strbuf_puts(buf
, "Failed to parse log level.\n");
1356 pa_log_set_level(level
);
1361 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1365 pa_core_assert_ref(c
);
1370 if (!(m
= pa_tokenizer_get(t
, 1))) {
1371 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1375 if ((b
= pa_parse_boolean(m
)) < 0) {
1376 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1380 pa_log_set_flags(PA_LOG_PRINT_META
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1385 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1389 pa_core_assert_ref(c
);
1394 if (!(m
= pa_tokenizer_get(t
, 1))) {
1395 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1399 if ((b
= pa_parse_boolean(m
)) < 0) {
1400 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1404 pa_log_set_flags(PA_LOG_PRINT_TIME
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1409 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1413 pa_core_assert_ref(c
);
1418 if (!(m
= pa_tokenizer_get(t
, 1))) {
1419 pa_strbuf_puts(buf
, "You need to specify a backtrace level.\n");
1423 if (pa_atou(m
, &nframes
) < 0 || nframes
>= 1000) {
1424 pa_strbuf_puts(buf
, "Failed to parse backtrace level.\n");
1428 pa_log_set_show_backtrace(nframes
);
1433 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1437 pa_core_assert_ref(c
);
1442 if (!(n
= pa_tokenizer_get(t
, 1))) {
1443 pa_strbuf_puts(buf
, "You need to specify a card either by its name or its index.\n");
1447 if (!(p
= pa_tokenizer_get(t
, 2))) {
1448 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1452 if (!(card
= pa_namereg_get(c
, n
, PA_NAMEREG_CARD
))) {
1453 pa_strbuf_puts(buf
, "No card found by this name or index.\n");
1457 if (pa_card_set_profile(card
, p
) < 0) {
1458 pa_strbuf_printf(buf
, "Failed to set card profile to '%s'.\n", p
);
1465 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1475 pa_core_assert_ref(c
);
1483 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime_r(&now
, txt
));
1485 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime(&now
));
1488 for (m
= pa_idxset_first(c
->modules
, &idx
); m
; m
= pa_idxset_next(c
->modules
, &idx
)) {
1490 pa_strbuf_printf(buf
, "load-module %s", m
->name
);
1493 pa_strbuf_printf(buf
, " %s", m
->argument
);
1495 pa_strbuf_puts(buf
, "\n");
1500 for (sink
= pa_idxset_first(c
->sinks
, &idx
); sink
; sink
= pa_idxset_next(c
->sinks
, &idx
)) {
1503 pa_strbuf_puts(buf
, "\n");
1507 pa_strbuf_printf(buf
, "set-sink-volume %s 0x%03x\n", sink
->name
, pa_cvolume_avg(pa_sink_get_volume(sink
, FALSE
)));
1508 pa_strbuf_printf(buf
, "set-sink-mute %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_mute(sink
, FALSE
)));
1509 pa_strbuf_printf(buf
, "suspend-sink %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_state(sink
) == PA_SINK_SUSPENDED
));
1512 for (source
= pa_idxset_first(c
->sources
, &idx
); source
; source
= pa_idxset_next(c
->sources
, &idx
)) {
1515 pa_strbuf_puts(buf
, "\n");
1519 pa_strbuf_printf(buf
, "set-source-volume %s 0x%03x\n", source
->name
, pa_cvolume_avg(pa_source_get_volume(source
, FALSE
)));
1520 pa_strbuf_printf(buf
, "set-source-mute %s %s\n", source
->name
, pa_yes_no(pa_source_get_mute(source
, FALSE
)));
1521 pa_strbuf_printf(buf
, "suspend-source %s %s\n", source
->name
, pa_yes_no(pa_source_get_state(source
) == PA_SOURCE_SUSPENDED
));
1524 for (card
= pa_idxset_first(c
->cards
, &idx
); card
; card
= pa_idxset_next(c
->cards
, &idx
)) {
1527 pa_strbuf_puts(buf
, "\n");
1531 if (card
->active_profile
)
1532 pa_strbuf_printf(buf
, "set-card-profile %s %s\n", card
->name
, card
->active_profile
->name
);
1537 if ((sink
= pa_namereg_get_default_sink(c
))) {
1539 pa_strbuf_puts(buf
, "\n");
1542 pa_strbuf_printf(buf
, "set-default-sink %s\n", sink
->name
);
1545 if ((source
= pa_namereg_get_default_source(c
))) {
1547 pa_strbuf_puts(buf
, "\n");
1550 pa_strbuf_printf(buf
, "set-default-source %s\n", source
->name
);
1553 pa_strbuf_puts(buf
, "\n### EOF\n");
1558 int pa_cli_command_execute_line_stateful(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
, int *ifstate
) {
1565 cs
= s
+strspn(s
, whitespace
);
1567 if (*cs
== '#' || !*cs
)
1569 else if (*cs
== '.') {
1570 if (!strcmp(cs
, META_ELSE
)) {
1571 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1572 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1574 } else if (*ifstate
== IFSTATE_TRUE
)
1575 *ifstate
= IFSTATE_FALSE
;
1577 *ifstate
= IFSTATE_TRUE
;
1579 } else if (!strcmp(cs
, META_ENDIF
)) {
1580 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1581 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1584 *ifstate
= IFSTATE_NONE
;
1587 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1589 if (!strcmp(cs
, META_FAIL
))
1591 else if (!strcmp(cs
, META_NOFAIL
))
1595 l
= strcspn(cs
, whitespace
);
1597 if (l
== sizeof(META_INCLUDE
)-1 && !strncmp(cs
, META_INCLUDE
, l
)) {
1598 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1599 if (pa_cli_command_execute_file(c
, filename
, buf
, fail
) < 0)
1602 } else if (l
== sizeof(META_IFEXISTS
)-1 && !strncmp(cs
, META_IFEXISTS
, l
)) {
1604 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1606 } else if (*ifstate
!= IFSTATE_NONE
) {
1607 pa_strbuf_printf(buf
, "Nested %s commands not supported\n", cs
);
1610 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1612 /* Search DL_SEARCH_PATH unless the filename is absolute */
1613 if (filename
[0] == PA_PATH_SEP_CHAR
) {
1615 *ifstate
= access(filename
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1616 pa_log_debug("Checking for existance of '%s': %s", filename
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1619 const char *paths
, *state
= NULL
;
1622 if (!(paths
= lt_dlgetsearchpath()))
1625 while ((p
= pa_split(paths
, ":", &state
))) {
1628 pathname
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", p
, filename
);
1631 *ifstate
= access(pathname
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1632 pa_log_debug("Checking for existance of '%s': %s", pathname
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1636 if (*ifstate
== IFSTATE_TRUE
)
1643 pa_strbuf_printf(buf
, "Invalid meta command: %s\n", cs
);
1644 if (*fail
) return -1;
1648 const struct command
*command
;
1652 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1655 l
= strcspn(cs
, whitespace
);
1657 for (command
= commands
; command
->name
; command
++)
1658 if (strlen(command
->name
) == l
&& !strncmp(cs
, command
->name
, l
)) {
1660 pa_tokenizer
*t
= pa_tokenizer_new(cs
, command
->args
);
1662 ret
= command
->proc(c
, t
, buf
, fail
);
1663 pa_tokenizer_free(t
);
1666 if (ret
< 0 && *fail
)
1673 pa_strbuf_printf(buf
, "Unknown command: %s\n", cs
);
1682 int pa_cli_command_execute_line(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1683 return pa_cli_command_execute_line_stateful(c
, s
, buf
, fail
, NULL
);
1686 int pa_cli_command_execute_file_stream(pa_core
*c
, FILE *f
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1688 int ifstate
= IFSTATE_NONE
;
1690 pa_bool_t _fail
= TRUE
;
1699 while (fgets(line
, sizeof(line
), f
)) {
1702 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
)
1713 int pa_cli_command_execute_file(pa_core
*c
, const char *fn
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1716 pa_bool_t _fail
= TRUE
;
1725 if (!(f
= fopen(fn
, "r"))) {
1726 pa_strbuf_printf(buf
, "open('%s') failed: %s\n", fn
, pa_cstrerror(errno
));
1732 ret
= pa_cli_command_execute_file_stream(c
, f
, buf
, fail
);
1743 int pa_cli_command_execute(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1745 int ifstate
= IFSTATE_NONE
;
1746 pa_bool_t _fail
= TRUE
;
1757 size_t l
= strcspn(p
, linebreak
);
1758 char *line
= pa_xstrndup(p
, l
);
1760 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
) {
1767 p
+= strspn(p
, linebreak
);