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
));
487 pa_strbuf_printf(buf
, "Warning, deprecated: %s\n", i
->deprecated
);
492 pa_strbuf_puts(buf
, "Failed to open module.\n");
497 static int pa_cli_command_sink_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
503 pa_core_assert_ref(c
);
508 if (!(n
= pa_tokenizer_get(t
, 1))) {
509 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
513 if (!(v
= pa_tokenizer_get(t
, 2))) {
514 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
518 if (pa_atou(v
, &volume
) < 0) {
519 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
523 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
524 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
528 pa_cvolume_set(&cvolume
, sink
->sample_spec
.channels
, volume
);
529 pa_sink_set_volume(sink
, &cvolume
, TRUE
, TRUE
, TRUE
);
533 static int pa_cli_command_sink_input_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
540 pa_core_assert_ref(c
);
545 if (!(n
= pa_tokenizer_get(t
, 1))) {
546 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
550 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
551 pa_strbuf_puts(buf
, "Failed to parse index.\n");
555 if (!(v
= pa_tokenizer_get(t
, 2))) {
556 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
560 if (pa_atou(v
, &volume
) < 0) {
561 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
565 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
566 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
570 pa_cvolume_set(&cvolume
, si
->sample_spec
.channels
, volume
);
571 pa_sink_input_set_volume(si
, &cvolume
, TRUE
, TRUE
);
575 static int pa_cli_command_source_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
581 pa_core_assert_ref(c
);
586 if (!(n
= pa_tokenizer_get(t
, 1))) {
587 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
591 if (!(v
= pa_tokenizer_get(t
, 2))) {
592 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
596 if (pa_atou(v
, &volume
) < 0) {
597 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
601 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
602 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
606 pa_cvolume_set(&cvolume
, source
->sample_spec
.channels
, volume
);
607 pa_source_set_volume(source
, &cvolume
);
611 static int pa_cli_command_sink_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
616 pa_core_assert_ref(c
);
621 if (!(n
= pa_tokenizer_get(t
, 1))) {
622 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
626 if (!(m
= pa_tokenizer_get(t
, 2))) {
627 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
631 if ((mute
= pa_parse_boolean(m
)) < 0) {
632 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
636 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
637 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
641 pa_sink_set_mute(sink
, mute
);
645 static int pa_cli_command_source_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
650 pa_core_assert_ref(c
);
655 if (!(n
= pa_tokenizer_get(t
, 1))) {
656 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
660 if (!(m
= pa_tokenizer_get(t
, 2))) {
661 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
665 if ((mute
= pa_parse_boolean(m
)) < 0) {
666 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
670 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
671 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
675 pa_source_set_mute(source
, mute
);
679 static int pa_cli_command_update_sink_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
684 pa_core_assert_ref(c
);
689 if (!(n
= pa_tokenizer_get(t
, 1))) {
690 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
694 if (!(s
= pa_tokenizer_get(t
, 2))) {
695 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
699 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
700 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
704 if (!(p
= pa_proplist_from_string(s
))) {
705 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
709 pa_sink_update_proplist(sink
, PA_UPDATE_REPLACE
, p
);
716 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
721 pa_core_assert_ref(c
);
726 if (!(n
= pa_tokenizer_get(t
, 1))) {
727 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
731 if (!(s
= pa_tokenizer_get(t
, 2))) {
732 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
736 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
737 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
741 if (!(p
= pa_proplist_from_string(s
))) {
742 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
746 pa_source_update_proplist(source
, PA_UPDATE_REPLACE
, p
);
753 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
759 pa_core_assert_ref(c
);
764 if (!(n
= pa_tokenizer_get(t
, 1))) {
765 pa_strbuf_puts(buf
, "You need to specify a sink input either by index.\n");
769 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
770 pa_strbuf_puts(buf
, "Failed to parse index.\n");
774 if (!(s
= pa_tokenizer_get(t
, 2))) {
775 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
779 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
780 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
784 if (!(p
= pa_proplist_from_string(s
))) {
785 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
789 pa_sink_input_update_proplist(si
, PA_UPDATE_REPLACE
, p
);
796 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
798 pa_source_output
*so
;
802 pa_core_assert_ref(c
);
807 if (!(n
= pa_tokenizer_get(t
, 1))) {
808 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
812 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
813 pa_strbuf_puts(buf
, "Failed to parse index.\n");
817 if (!(s
= pa_tokenizer_get(t
, 2))) {
818 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
822 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
823 pa_strbuf_puts(buf
, "No source output found with this index.\n");
827 if (!(p
= pa_proplist_from_string(s
))) {
828 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
832 pa_source_output_update_proplist(so
, PA_UPDATE_REPLACE
, p
);
839 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
845 pa_core_assert_ref(c
);
850 if (!(n
= pa_tokenizer_get(t
, 1))) {
851 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
855 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
856 pa_strbuf_puts(buf
, "Failed to parse index.\n");
860 if (!(v
= pa_tokenizer_get(t
, 2))) {
861 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
865 if ((mute
= pa_parse_boolean(v
)) < 0) {
866 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
870 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
871 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
875 pa_sink_input_set_mute(si
, mute
, TRUE
);
879 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
883 pa_core_assert_ref(c
);
888 if (!(n
= pa_tokenizer_get(t
, 1))) {
889 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
893 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
)))
894 pa_namereg_set_default_sink(c
, s
);
896 pa_strbuf_printf(buf
, "Sink %s does not exist.\n", n
);
901 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
905 pa_core_assert_ref(c
);
910 if (!(n
= pa_tokenizer_get(t
, 1))) {
911 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
915 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
)))
916 pa_namereg_set_default_source(c
, s
);
918 pa_strbuf_printf(buf
, "Source %s does not exist.\n", n
);
922 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
927 pa_core_assert_ref(c
);
932 if (!(n
= pa_tokenizer_get(t
, 1))) {
933 pa_strbuf_puts(buf
, "You need to specify a client by its index.\n");
937 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
938 pa_strbuf_puts(buf
, "Failed to parse index.\n");
942 if (!(client
= pa_idxset_get_by_index(c
->clients
, idx
))) {
943 pa_strbuf_puts(buf
, "No client found by this index.\n");
947 pa_client_kill(client
);
951 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
953 pa_sink_input
*sink_input
;
956 pa_core_assert_ref(c
);
961 if (!(n
= pa_tokenizer_get(t
, 1))) {
962 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
966 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
967 pa_strbuf_puts(buf
, "Failed to parse index.\n");
971 if (!(sink_input
= pa_idxset_get_by_index(c
->sink_inputs
, idx
))) {
972 pa_strbuf_puts(buf
, "No sink input found by this index.\n");
976 pa_sink_input_kill(sink_input
);
980 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
982 pa_source_output
*source_output
;
985 pa_core_assert_ref(c
);
990 if (!(n
= pa_tokenizer_get(t
, 1))) {
991 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
995 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
996 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1000 if (!(source_output
= pa_idxset_get_by_index(c
->source_outputs
, idx
))) {
1001 pa_strbuf_puts(buf
, "No source output found by this index.\n");
1005 pa_source_output_kill(source_output
);
1009 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1012 pa_core_assert_ref(c
);
1017 pa_assert_se(s
= pa_scache_list_to_string(c
));
1018 pa_strbuf_puts(buf
, s
);
1024 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1025 const char *n
, *sink_name
;
1029 pa_core_assert_ref(c
);
1034 if (!(n
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1035 pa_strbuf_puts(buf
, "You need to specify a sample name and a sink name.\n");
1039 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1040 pa_strbuf_puts(buf
, "No sink by that name.\n");
1044 if (pa_scache_play_item(c
, n
, sink
, PA_VOLUME_NORM
, NULL
, &idx
) < 0) {
1045 pa_strbuf_puts(buf
, "Failed to play sample.\n");
1049 pa_strbuf_printf(buf
, "Playing on sink input #%i\n", idx
);
1054 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1057 pa_core_assert_ref(c
);
1062 if (!(n
= pa_tokenizer_get(t
, 1))) {
1063 pa_strbuf_puts(buf
, "You need to specify a sample name.\n");
1067 if (pa_scache_remove_item(c
, n
) < 0) {
1068 pa_strbuf_puts(buf
, "Failed to remove sample.\n");
1075 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1076 const char *fname
, *n
;
1079 pa_core_assert_ref(c
);
1084 if (!(fname
= pa_tokenizer_get(t
, 2)) || !(n
= pa_tokenizer_get(t
, 1))) {
1085 pa_strbuf_puts(buf
, "You need to specify a file name and a sample name.\n");
1089 if (strstr(pa_tokenizer_get(t
, 0), "lazy"))
1090 r
= pa_scache_add_file_lazy(c
, n
, fname
, NULL
);
1092 r
= pa_scache_add_file(c
, n
, fname
, NULL
);
1095 pa_strbuf_puts(buf
, "Failed to load sound file.\n");
1100 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1103 pa_core_assert_ref(c
);
1108 if (!(pname
= pa_tokenizer_get(t
, 1))) {
1109 pa_strbuf_puts(buf
, "You need to specify a path name.\n");
1113 if (pa_scache_add_directory_lazy(c
, pname
) < 0) {
1114 pa_strbuf_puts(buf
, "Failed to load directory.\n");
1121 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1122 const char *fname
, *sink_name
;
1125 pa_core_assert_ref(c
);
1130 if (!(fname
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1131 pa_strbuf_puts(buf
, "You need to specify a file name and a sink name.\n");
1135 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1136 pa_strbuf_puts(buf
, "No sink by that name.\n");
1141 return pa_play_file(sink
, fname
, NULL
);
1144 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1145 pa_core_assert_ref(c
);
1150 pa_shared_dump(c
, buf
);
1154 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1155 pa_core_assert_ref(c
);
1160 pa_mempool_vacuum(c
->mempool
);
1165 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1171 pa_core_assert_ref(c
);
1176 if (!(n
= pa_tokenizer_get(t
, 1))) {
1177 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
1181 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1182 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1186 if (!(k
= pa_tokenizer_get(t
, 2))) {
1187 pa_strbuf_puts(buf
, "You need to specify a sink.\n");
1191 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
1192 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
1196 if (!(sink
= pa_namereg_get(c
, k
, PA_NAMEREG_SINK
))) {
1197 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1201 if (pa_sink_input_move_to(si
, sink
, TRUE
) < 0) {
1202 pa_strbuf_puts(buf
, "Moved failed.\n");
1208 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1210 pa_source_output
*so
;
1214 pa_core_assert_ref(c
);
1219 if (!(n
= pa_tokenizer_get(t
, 1))) {
1220 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
1224 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1225 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1229 if (!(k
= pa_tokenizer_get(t
, 2))) {
1230 pa_strbuf_puts(buf
, "You need to specify a source.\n");
1234 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
1235 pa_strbuf_puts(buf
, "No source output found with this index.\n");
1239 if (!(source
= pa_namereg_get(c
, k
, PA_NAMEREG_SOURCE
))) {
1240 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1244 if (pa_source_output_move_to(so
, source
, TRUE
) < 0) {
1245 pa_strbuf_puts(buf
, "Moved failed.\n");
1251 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1256 pa_core_assert_ref(c
);
1261 if (!(n
= pa_tokenizer_get(t
, 1))) {
1262 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1266 if (!(m
= pa_tokenizer_get(t
, 2))) {
1267 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1271 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1272 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1276 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
1277 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1281 if ((r
= pa_sink_suspend(sink
, suspend
, PA_SUSPEND_USER
)) < 0)
1282 pa_strbuf_printf(buf
, "Failed to resume/suspend sink: %s\n", pa_strerror(r
));
1287 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1292 pa_core_assert_ref(c
);
1297 if (!(n
= pa_tokenizer_get(t
, 1))) {
1298 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1302 if (!(m
= pa_tokenizer_get(t
, 2))) {
1303 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1307 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1308 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1312 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
1313 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1317 if ((r
= pa_source_suspend(source
, suspend
, PA_SUSPEND_USER
)) < 0)
1318 pa_strbuf_printf(buf
, "Failed to resume/suspend source: %s\n", pa_strerror(r
));
1323 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1327 pa_core_assert_ref(c
);
1332 if (!(m
= pa_tokenizer_get(t
, 1))) {
1333 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1337 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1338 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1342 if ((r
= pa_sink_suspend_all(c
, suspend
, PA_SUSPEND_USER
)) < 0)
1343 pa_strbuf_printf(buf
, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r
));
1345 if ((r
= pa_source_suspend_all(c
, suspend
, PA_SUSPEND_USER
)) < 0)
1346 pa_strbuf_printf(buf
, "Failed to resume/suspend all sources: %s\n", pa_strerror(r
));
1351 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1355 pa_core_assert_ref(c
);
1360 if (!(m
= pa_tokenizer_get(t
, 1))) {
1361 pa_strbuf_puts(buf
, "You need to specify a log level (0..4).\n");
1365 if (pa_atou(m
, &level
) < 0 || level
>= PA_LOG_LEVEL_MAX
) {
1366 pa_strbuf_puts(buf
, "Failed to parse log level.\n");
1370 pa_log_set_level(level
);
1375 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1379 pa_core_assert_ref(c
);
1384 if (!(m
= pa_tokenizer_get(t
, 1))) {
1385 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1389 if ((b
= pa_parse_boolean(m
)) < 0) {
1390 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1394 pa_log_set_flags(PA_LOG_PRINT_META
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1399 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1403 pa_core_assert_ref(c
);
1408 if (!(m
= pa_tokenizer_get(t
, 1))) {
1409 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1413 if ((b
= pa_parse_boolean(m
)) < 0) {
1414 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1418 pa_log_set_flags(PA_LOG_PRINT_TIME
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1423 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1427 pa_core_assert_ref(c
);
1432 if (!(m
= pa_tokenizer_get(t
, 1))) {
1433 pa_strbuf_puts(buf
, "You need to specify a backtrace level.\n");
1437 if (pa_atou(m
, &nframes
) < 0 || nframes
>= 1000) {
1438 pa_strbuf_puts(buf
, "Failed to parse backtrace level.\n");
1442 pa_log_set_show_backtrace(nframes
);
1447 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1451 pa_core_assert_ref(c
);
1456 if (!(n
= pa_tokenizer_get(t
, 1))) {
1457 pa_strbuf_puts(buf
, "You need to specify a card either by its name or its index.\n");
1461 if (!(p
= pa_tokenizer_get(t
, 2))) {
1462 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1466 if (!(card
= pa_namereg_get(c
, n
, PA_NAMEREG_CARD
))) {
1467 pa_strbuf_puts(buf
, "No card found by this name or index.\n");
1471 if (pa_card_set_profile(card
, p
, TRUE
) < 0) {
1472 pa_strbuf_printf(buf
, "Failed to set card profile to '%s'.\n", p
);
1479 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1489 pa_core_assert_ref(c
);
1497 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime_r(&now
, txt
));
1499 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime(&now
));
1502 for (m
= pa_idxset_first(c
->modules
, &idx
); m
; m
= pa_idxset_next(c
->modules
, &idx
)) {
1504 pa_strbuf_printf(buf
, "load-module %s", m
->name
);
1507 pa_strbuf_printf(buf
, " %s", m
->argument
);
1509 pa_strbuf_puts(buf
, "\n");
1514 for (sink
= pa_idxset_first(c
->sinks
, &idx
); sink
; sink
= pa_idxset_next(c
->sinks
, &idx
)) {
1517 pa_strbuf_puts(buf
, "\n");
1521 pa_strbuf_printf(buf
, "set-sink-volume %s 0x%03x\n", sink
->name
, pa_cvolume_avg(pa_sink_get_volume(sink
, FALSE
, TRUE
)));
1522 pa_strbuf_printf(buf
, "set-sink-mute %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_mute(sink
, FALSE
)));
1523 pa_strbuf_printf(buf
, "suspend-sink %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_state(sink
) == PA_SINK_SUSPENDED
));
1526 for (source
= pa_idxset_first(c
->sources
, &idx
); source
; source
= pa_idxset_next(c
->sources
, &idx
)) {
1529 pa_strbuf_puts(buf
, "\n");
1533 pa_strbuf_printf(buf
, "set-source-volume %s 0x%03x\n", source
->name
, pa_cvolume_avg(pa_source_get_volume(source
, FALSE
)));
1534 pa_strbuf_printf(buf
, "set-source-mute %s %s\n", source
->name
, pa_yes_no(pa_source_get_mute(source
, FALSE
)));
1535 pa_strbuf_printf(buf
, "suspend-source %s %s\n", source
->name
, pa_yes_no(pa_source_get_state(source
) == PA_SOURCE_SUSPENDED
));
1538 for (card
= pa_idxset_first(c
->cards
, &idx
); card
; card
= pa_idxset_next(c
->cards
, &idx
)) {
1541 pa_strbuf_puts(buf
, "\n");
1545 if (card
->active_profile
)
1546 pa_strbuf_printf(buf
, "set-card-profile %s %s\n", card
->name
, card
->active_profile
->name
);
1551 if ((sink
= pa_namereg_get_default_sink(c
))) {
1553 pa_strbuf_puts(buf
, "\n");
1556 pa_strbuf_printf(buf
, "set-default-sink %s\n", sink
->name
);
1559 if ((source
= pa_namereg_get_default_source(c
))) {
1561 pa_strbuf_puts(buf
, "\n");
1564 pa_strbuf_printf(buf
, "set-default-source %s\n", source
->name
);
1567 pa_strbuf_puts(buf
, "\n### EOF\n");
1572 int pa_cli_command_execute_line_stateful(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
, int *ifstate
) {
1579 cs
= s
+strspn(s
, whitespace
);
1581 if (*cs
== '#' || !*cs
)
1583 else if (*cs
== '.') {
1584 if (!strcmp(cs
, META_ELSE
)) {
1585 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1586 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1588 } else if (*ifstate
== IFSTATE_TRUE
)
1589 *ifstate
= IFSTATE_FALSE
;
1591 *ifstate
= IFSTATE_TRUE
;
1593 } else if (!strcmp(cs
, META_ENDIF
)) {
1594 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1595 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1598 *ifstate
= IFSTATE_NONE
;
1601 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1603 if (!strcmp(cs
, META_FAIL
))
1605 else if (!strcmp(cs
, META_NOFAIL
))
1609 l
= strcspn(cs
, whitespace
);
1611 if (l
== sizeof(META_INCLUDE
)-1 && !strncmp(cs
, META_INCLUDE
, l
)) {
1612 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1613 if (pa_cli_command_execute_file(c
, filename
, buf
, fail
) < 0)
1616 } else if (l
== sizeof(META_IFEXISTS
)-1 && !strncmp(cs
, META_IFEXISTS
, l
)) {
1618 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1620 } else if (*ifstate
!= IFSTATE_NONE
) {
1621 pa_strbuf_printf(buf
, "Nested %s commands not supported\n", cs
);
1624 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1626 /* Search DL_SEARCH_PATH unless the filename is absolute */
1627 if (filename
[0] == PA_PATH_SEP_CHAR
) {
1629 *ifstate
= access(filename
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1630 pa_log_debug("Checking for existance of '%s': %s", filename
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1633 const char *paths
, *state
= NULL
;
1636 if (!(paths
= lt_dlgetsearchpath()))
1639 while ((p
= pa_split(paths
, ":", &state
))) {
1642 pathname
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", p
, filename
);
1645 *ifstate
= access(pathname
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1646 pa_log_debug("Checking for existance of '%s': %s", pathname
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1650 if (*ifstate
== IFSTATE_TRUE
)
1657 pa_strbuf_printf(buf
, "Invalid meta command: %s\n", cs
);
1658 if (*fail
) return -1;
1662 const struct command
*command
;
1666 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1669 l
= strcspn(cs
, whitespace
);
1671 for (command
= commands
; command
->name
; command
++)
1672 if (strlen(command
->name
) == l
&& !strncmp(cs
, command
->name
, l
)) {
1674 pa_tokenizer
*t
= pa_tokenizer_new(cs
, command
->args
);
1676 ret
= command
->proc(c
, t
, buf
, fail
);
1677 pa_tokenizer_free(t
);
1680 if (ret
< 0 && *fail
)
1687 pa_strbuf_printf(buf
, "Unknown command: %s\n", cs
);
1696 int pa_cli_command_execute_line(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1697 return pa_cli_command_execute_line_stateful(c
, s
, buf
, fail
, NULL
);
1700 int pa_cli_command_execute_file_stream(pa_core
*c
, FILE *f
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1702 int ifstate
= IFSTATE_NONE
;
1704 pa_bool_t _fail
= TRUE
;
1713 while (fgets(line
, sizeof(line
), f
)) {
1716 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
)
1727 int pa_cli_command_execute_file(pa_core
*c
, const char *fn
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1730 pa_bool_t _fail
= TRUE
;
1739 if (!(f
= fopen(fn
, "r"))) {
1740 pa_strbuf_printf(buf
, "open('%s') failed: %s\n", fn
, pa_cstrerror(errno
));
1746 ret
= pa_cli_command_execute_file_stream(c
, f
, buf
, fail
);
1757 int pa_cli_command_execute(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1759 int ifstate
= IFSTATE_NONE
;
1760 pa_bool_t _fail
= TRUE
;
1771 size_t l
= strcspn(p
, linebreak
);
1772 char *line
= pa_xstrndup(p
, l
);
1774 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
) {
1781 p
+= strspn(p
, linebreak
);