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>
36 #include <pulsecore/module.h>
37 #include <pulsecore/sink.h>
38 #include <pulsecore/source.h>
39 #include <pulsecore/client.h>
40 #include <pulsecore/sink-input.h>
41 #include <pulsecore/source-output.h>
42 #include <pulsecore/tokenizer.h>
43 #include <pulsecore/strbuf.h>
44 #include <pulsecore/namereg.h>
45 #include <pulsecore/cli-text.h>
46 #include <pulsecore/core-scache.h>
47 #include <pulsecore/sample-util.h>
48 #include <pulsecore/sound-file.h>
49 #include <pulsecore/play-memchunk.h>
50 #include <pulsecore/sound-file-stream.h>
51 #include <pulsecore/shared.h>
52 #include <pulsecore/core-util.h>
53 #include <pulsecore/core-error.h>
54 #include <pulsecore/modinfo.h>
56 #include "cli-command.h"
60 int (*proc
) (pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
65 #define META_INCLUDE ".include"
66 #define META_FAIL ".fail"
67 #define META_NOFAIL ".nofail"
68 #define META_IFEXISTS ".ifexists"
69 #define META_ELSE ".else"
70 #define META_ENDIF ".endif"
78 /* Prototypes for all available commands */
79 static int pa_cli_command_exit(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
80 static int pa_cli_command_help(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
81 static int pa_cli_command_modules(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
82 static int pa_cli_command_clients(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
83 static int pa_cli_command_cards(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
84 static int pa_cli_command_sinks(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
85 static int pa_cli_command_sources(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
86 static int pa_cli_command_sink_inputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
87 static int pa_cli_command_source_outputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
88 static int pa_cli_command_stat(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
89 static int pa_cli_command_info(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
90 static int pa_cli_command_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
91 static int pa_cli_command_unload(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
92 static int pa_cli_command_describe(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
93 static int pa_cli_command_sink_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
94 static int pa_cli_command_sink_input_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
95 static int pa_cli_command_source_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
96 static int pa_cli_command_sink_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
97 static int pa_cli_command_source_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
98 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
99 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
100 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
101 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
102 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
103 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
104 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
105 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
106 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
107 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
108 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
109 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
110 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
111 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
112 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
113 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
114 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
115 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
116 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
117 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
118 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
119 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
120 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
121 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
122 static int pa_cli_command_update_sink_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
123 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
124 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
125 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
126 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
128 /* A method table for all available commands */
130 static const struct command commands
[] = {
131 { "exit", pa_cli_command_exit
, "Terminate the daemon", 1 },
132 { "help", pa_cli_command_help
, "Show this help", 1 },
133 { "list-modules", pa_cli_command_modules
, "List loaded modules", 1 },
134 { "list-sinks", pa_cli_command_sinks
, "List loaded sinks", 1 },
135 { "list-sources", pa_cli_command_sources
, "List loaded sources", 1 },
136 { "list-clients", pa_cli_command_clients
, "List loaded clients", 1 },
137 { "list-sink-inputs", pa_cli_command_sink_inputs
, "List sink inputs", 1 },
138 { "list-source-outputs", pa_cli_command_source_outputs
, "List source outputs", 1 },
139 { "list-cards", pa_cli_command_cards
, "List cards", 1 },
140 { "stat", pa_cli_command_stat
, "Show memory block statistics", 1 },
141 { "info", pa_cli_command_info
, "Show comprehensive status", 1 },
142 { "ls", pa_cli_command_info
, NULL
, 1 },
143 { "list", pa_cli_command_info
, NULL
, 1 },
144 { "load-module", pa_cli_command_load
, "Load a module (args: name, arguments)", 3},
145 { "unload-module", pa_cli_command_unload
, "Unload a module (args: index)", 2},
146 { "describe-module", pa_cli_command_describe
, "Describe a module (arg: name)", 2},
147 { "set-sink-volume", pa_cli_command_sink_volume
, "Set the volume of a sink (args: index|name, volume)", 3},
148 { "set-sink-input-volume", pa_cli_command_sink_input_volume
, "Set the volume of a sink input (args: index, volume)", 3},
149 { "set-source-volume", pa_cli_command_source_volume
, "Set the volume of a source (args: index|name, volume)", 3},
150 { "set-sink-mute", pa_cli_command_sink_mute
, "Set the mute switch of a sink (args: index|name, bool)", 3},
151 { "set-sink-input-mute", pa_cli_command_sink_input_mute
, "Set the mute switch of a sink input (args: index, bool)", 3},
152 { "set-source-mute", pa_cli_command_source_mute
, "Set the mute switch of a source (args: index|name, bool)", 3},
153 { "update-sink-proplist", pa_cli_command_update_sink_proplist
, "Update the properties of a sink (args: index|name, properties)", 3},
154 { "update-source-proplist", pa_cli_command_update_source_proplist
, "Update the properties of a source (args: index|name, properties)", 3},
155 { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist
, "Update the properties of a sink input (args: index, properties)", 3},
156 { "update-source-output-proplist", pa_cli_command_update_source_output_proplist
, "Update the properties of a source_output (args: index, properties)", 3},
157 { "set-default-sink", pa_cli_command_sink_default
, "Set the default sink (args: index|name)", 2},
158 { "set-default-source", pa_cli_command_source_default
, "Set the default source (args: index|name)", 2},
159 { "kill-client", pa_cli_command_kill_client
, "Kill a client (args: index)", 2},
160 { "kill-sink-input", pa_cli_command_kill_sink_input
, "Kill a sink input (args: index)", 2},
161 { "kill-source-output", pa_cli_command_kill_source_output
, "Kill a source output (args: index)", 2},
162 { "list-samples", pa_cli_command_scache_list
, "List all entries in the sample cache", 1},
163 { "play-sample", pa_cli_command_scache_play
, "Play a sample from the sample cache (args: name, sink|index)", 3},
164 { "remove-sample", pa_cli_command_scache_remove
, "Remove a sample from the sample cache (args: name)", 2},
165 { "load-sample", pa_cli_command_scache_load
, "Load a sound file into the sample cache (args: name, filename)", 3},
166 { "load-sample-lazy", pa_cli_command_scache_load
, "Lazily load a sound file into the sample cache (args: name, filename)", 3},
167 { "load-sample-dir-lazy", pa_cli_command_scache_load_dir
, "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
168 { "play-file", pa_cli_command_play_file
, "Play a sound file (args: filename, sink|index)", 3},
169 { "dump", pa_cli_command_dump
, "Dump daemon configuration", 1},
170 { "shared", pa_cli_command_list_shared_props
, NULL
, 1},
171 { "move-sink-input", pa_cli_command_move_sink_input
, "Move sink input to another sink (args: index, sink)", 3},
172 { "move-source-output", pa_cli_command_move_source_output
, "Move source output to another source (args: index, source)", 3},
173 { "vacuum", pa_cli_command_vacuum
, NULL
, 1},
174 { "suspend-sink", pa_cli_command_suspend_sink
, "Suspend sink (args: index|name, bool)", 3},
175 { "suspend-source", pa_cli_command_suspend_source
, "Suspend source (args: index|name, bool)", 3},
176 { "suspend", pa_cli_command_suspend
, "Suspend all sinks and all sources (args: bool)", 2},
177 { "set-card-profile", pa_cli_command_card_profile
, "Change the profile of a card (aargs: index, name)", 3},
178 { "set-log-level", pa_cli_command_log_level
, "Change the log level (args: numeric level)", 2},
179 { "set-log-meta", pa_cli_command_log_meta
, "Show source code location in log messages (args: bool)", 2},
180 { "set-log-time", pa_cli_command_log_time
, "Show timestamps in log messages (args: bool)", 2},
181 { "set-log-backtrace", pa_cli_command_log_backtrace
, "Show bakctrace in log messages (args: frames)", 2},
182 { NULL
, NULL
, NULL
, 0 }
185 static const char whitespace
[] = " \t\n\r";
186 static const char linebreak
[] = "\n\r";
188 static uint32_t parse_index(const char *n
) {
191 if (pa_atou(n
, &idx
) < 0)
192 return (uint32_t) PA_IDXSET_INVALID
;
197 static int pa_cli_command_exit(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
198 pa_core_assert_ref(c
);
203 if (pa_core_exit(c
, FALSE
, 0) < 0)
204 pa_strbuf_puts(buf
, "Not allowed to terminate daemon.\n");
209 static int pa_cli_command_help(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
210 const struct command
*command
;
212 pa_core_assert_ref(c
);
217 pa_strbuf_puts(buf
, "Available commands:\n");
219 for (command
= commands
; command
->name
; command
++)
221 pa_strbuf_printf(buf
, " %-25s %s\n", command
->name
, command
->help
);
225 static int pa_cli_command_modules(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
228 pa_core_assert_ref(c
);
233 pa_assert_se(s
= pa_module_list_to_string(c
));
234 pa_strbuf_puts(buf
, s
);
239 static int pa_cli_command_clients(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
242 pa_core_assert_ref(c
);
247 pa_assert_se(s
= pa_client_list_to_string(c
));
248 pa_strbuf_puts(buf
, s
);
253 static int pa_cli_command_cards(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
256 pa_core_assert_ref(c
);
261 pa_assert_se(s
= pa_card_list_to_string(c
));
262 pa_strbuf_puts(buf
, s
);
267 static int pa_cli_command_sinks(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
270 pa_core_assert_ref(c
);
275 pa_assert_se(s
= pa_sink_list_to_string(c
));
276 pa_strbuf_puts(buf
, s
);
281 static int pa_cli_command_sources(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
284 pa_core_assert_ref(c
);
289 pa_assert_se(s
= pa_source_list_to_string(c
));
290 pa_strbuf_puts(buf
, s
);
295 static int pa_cli_command_sink_inputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
298 pa_core_assert_ref(c
);
303 pa_assert_se(s
= pa_sink_input_list_to_string(c
));
304 pa_strbuf_puts(buf
, s
);
309 static int pa_cli_command_source_outputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
312 pa_core_assert_ref(c
);
317 pa_assert_se(s
= pa_source_output_list_to_string(c
));
318 pa_strbuf_puts(buf
, s
);
323 static int pa_cli_command_stat(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
324 char ss
[PA_SAMPLE_SPEC_SNPRINT_MAX
];
325 char cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
327 const pa_mempool_stat
*stat
;
330 pa_source
*def_source
;
332 static const char* const type_table
[PA_MEMBLOCK_TYPE_MAX
] = {
333 [PA_MEMBLOCK_POOL
] = "POOL",
334 [PA_MEMBLOCK_POOL_EXTERNAL
] = "POOL_EXTERNAL",
335 [PA_MEMBLOCK_APPENDED
] = "APPENDED",
336 [PA_MEMBLOCK_USER
] = "USER",
337 [PA_MEMBLOCK_FIXED
] = "FIXED",
338 [PA_MEMBLOCK_IMPORTED
] = "IMPORTED",
341 pa_core_assert_ref(c
);
346 stat
= pa_mempool_get_stat(c
->mempool
);
348 pa_strbuf_printf(buf
, "Memory blocks currently allocated: %u, size: %s.\n",
349 (unsigned) pa_atomic_load(&stat
->n_allocated
),
350 pa_bytes_snprint(s
, sizeof(s
), (unsigned) pa_atomic_load(&stat
->allocated_size
)));
352 pa_strbuf_printf(buf
, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
353 (unsigned) pa_atomic_load(&stat
->n_accumulated
),
354 pa_bytes_snprint(s
, sizeof(s
), (unsigned) pa_atomic_load(&stat
->accumulated_size
)));
356 pa_strbuf_printf(buf
, "Memory blocks imported from other processes: %u, size: %s.\n",
357 (unsigned) pa_atomic_load(&stat
->n_imported
),
358 pa_bytes_snprint(s
, sizeof(s
), (unsigned) pa_atomic_load(&stat
->imported_size
)));
360 pa_strbuf_printf(buf
, "Memory blocks exported to other processes: %u, size: %s.\n",
361 (unsigned) pa_atomic_load(&stat
->n_exported
),
362 pa_bytes_snprint(s
, sizeof(s
), (unsigned) pa_atomic_load(&stat
->exported_size
)));
364 pa_strbuf_printf(buf
, "Total sample cache size: %s.\n",
365 pa_bytes_snprint(s
, sizeof(s
), (unsigned) pa_scache_total_size(c
)));
367 pa_strbuf_printf(buf
, "Default sample spec: %s\n",
368 pa_sample_spec_snprint(ss
, sizeof(ss
), &c
->default_sample_spec
));
370 pa_strbuf_printf(buf
, "Default channel map: %s\n",
371 pa_channel_map_snprint(cm
, sizeof(cm
), &c
->default_channel_map
));
373 def_sink
= pa_namereg_get_default_sink(c
);
374 def_source
= pa_namereg_get_default_source(c
);
375 pa_strbuf_printf(buf
, "Default sink name: %s\n"
376 "Default source name: %s\n",
377 def_sink
? def_sink
->name
: "none",
378 def_source
? def_source
->name
: "none");
380 for (k
= 0; k
< PA_MEMBLOCK_TYPE_MAX
; k
++)
381 pa_strbuf_printf(buf
,
382 "Memory blocks of type %s: %u allocated/%u accumulated.\n",
384 (unsigned) pa_atomic_load(&stat
->n_allocated_by_type
[k
]),
385 (unsigned) pa_atomic_load(&stat
->n_accumulated_by_type
[k
]));
390 static int pa_cli_command_info(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
391 pa_core_assert_ref(c
);
396 pa_cli_command_stat(c
, t
, buf
, fail
);
397 pa_cli_command_modules(c
, t
, buf
, fail
);
398 pa_cli_command_sinks(c
, t
, buf
, fail
);
399 pa_cli_command_sources(c
, t
, buf
, fail
);
400 pa_cli_command_clients(c
, t
, buf
, fail
);
401 pa_cli_command_cards(c
, t
, buf
, fail
);
402 pa_cli_command_sink_inputs(c
, t
, buf
, fail
);
403 pa_cli_command_source_outputs(c
, t
, buf
, fail
);
404 pa_cli_command_scache_list(c
, t
, buf
, fail
);
408 static int pa_cli_command_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
411 pa_core_assert_ref(c
);
416 if (!(name
= pa_tokenizer_get(t
, 1))) {
417 pa_strbuf_puts(buf
, "You need to specify the module name and optionally arguments.\n");
421 if (!pa_module_load(c
, name
, pa_tokenizer_get(t
, 2))) {
422 pa_strbuf_puts(buf
, "Module load failed.\n");
429 static int pa_cli_command_unload(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
435 pa_core_assert_ref(c
);
440 if (!(i
= pa_tokenizer_get(t
, 1))) {
441 pa_strbuf_puts(buf
, "You need to specify the module index.\n");
445 idx
= (uint32_t) strtoul(i
, &e
, 10);
446 if (*e
|| !(m
= pa_idxset_get_by_index(c
->modules
, idx
))) {
447 pa_strbuf_puts(buf
, "Invalid module index.\n");
451 pa_module_unload_request(m
, FALSE
);
455 static int pa_cli_command_describe(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
459 pa_core_assert_ref(c
);
464 if (!(name
= pa_tokenizer_get(t
, 1))) {
465 pa_strbuf_puts(buf
, "You need to specify the module name.\n");
469 if ((i
= pa_modinfo_get_by_name(name
))) {
471 pa_strbuf_printf(buf
, "Name: %s\n", name
);
473 if (!i
->description
&& !i
->version
&& !i
->author
&& !i
->usage
)
474 pa_strbuf_printf(buf
, "No module information available\n");
477 pa_strbuf_printf(buf
, "Version: %s\n", i
->version
);
479 pa_strbuf_printf(buf
, "Description: %s\n", i
->description
);
481 pa_strbuf_printf(buf
, "Author: %s\n", i
->author
);
483 pa_strbuf_printf(buf
, "Usage: %s\n", i
->usage
);
484 pa_strbuf_printf(buf
, "Load Once: %s\n", pa_yes_no(i
->load_once
));
489 pa_strbuf_puts(buf
, "Failed to open module.\n");
494 static int pa_cli_command_sink_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
500 pa_core_assert_ref(c
);
505 if (!(n
= pa_tokenizer_get(t
, 1))) {
506 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
510 if (!(v
= pa_tokenizer_get(t
, 2))) {
511 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
515 if (pa_atou(v
, &volume
) < 0) {
516 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
520 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
521 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
525 pa_cvolume_set(&cvolume
, sink
->sample_spec
.channels
, volume
);
526 pa_sink_set_volume(sink
, &cvolume
, TRUE
, TRUE
);
530 static int pa_cli_command_sink_input_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
537 pa_core_assert_ref(c
);
542 if (!(n
= pa_tokenizer_get(t
, 1))) {
543 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
547 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
548 pa_strbuf_puts(buf
, "Failed to parse index.\n");
552 if (!(v
= pa_tokenizer_get(t
, 2))) {
553 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
557 if (pa_atou(v
, &volume
) < 0) {
558 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
562 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
563 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
567 pa_cvolume_set(&cvolume
, si
->sample_spec
.channels
, volume
);
568 pa_sink_input_set_volume(si
, &cvolume
, TRUE
);
572 static int pa_cli_command_source_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
578 pa_core_assert_ref(c
);
583 if (!(n
= pa_tokenizer_get(t
, 1))) {
584 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
588 if (!(v
= pa_tokenizer_get(t
, 2))) {
589 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
593 if (pa_atou(v
, &volume
) < 0) {
594 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
598 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
599 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
603 pa_cvolume_set(&cvolume
, source
->sample_spec
.channels
, volume
);
604 pa_source_set_volume(source
, &cvolume
);
608 static int pa_cli_command_sink_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
613 pa_core_assert_ref(c
);
618 if (!(n
= pa_tokenizer_get(t
, 1))) {
619 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
623 if (!(m
= pa_tokenizer_get(t
, 2))) {
624 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
628 if ((mute
= pa_parse_boolean(m
)) < 0) {
629 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
633 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
634 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
638 pa_sink_set_mute(sink
, mute
);
642 static int pa_cli_command_source_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
647 pa_core_assert_ref(c
);
652 if (!(n
= pa_tokenizer_get(t
, 1))) {
653 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
657 if (!(m
= pa_tokenizer_get(t
, 2))) {
658 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
662 if ((mute
= pa_parse_boolean(m
)) < 0) {
663 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
667 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
668 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
672 pa_source_set_mute(source
, mute
);
676 static int pa_cli_command_update_sink_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
681 pa_core_assert_ref(c
);
686 if (!(n
= pa_tokenizer_get(t
, 1))) {
687 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
691 if (!(s
= pa_tokenizer_get(t
, 2))) {
692 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
696 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
697 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
701 p
= pa_proplist_from_string(s
);
703 pa_sink_update_proplist(sink
, PA_UPDATE_REPLACE
, p
);
710 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
715 pa_core_assert_ref(c
);
720 if (!(n
= pa_tokenizer_get(t
, 1))) {
721 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
725 if (!(s
= pa_tokenizer_get(t
, 2))) {
726 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
730 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
731 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
735 p
= pa_proplist_from_string(s
);
737 pa_source_update_proplist(source
, PA_UPDATE_REPLACE
, p
);
744 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
750 pa_core_assert_ref(c
);
755 if (!(n
= pa_tokenizer_get(t
, 1))) {
756 pa_strbuf_puts(buf
, "You need to specify a sink input either by index.\n");
760 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
761 pa_strbuf_puts(buf
, "Failed to parse index.\n");
765 if (!(s
= pa_tokenizer_get(t
, 2))) {
766 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
770 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
771 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
775 p
= pa_proplist_from_string(s
);
777 pa_sink_input_update_proplist(si
, PA_UPDATE_REPLACE
, p
);
784 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
786 pa_source_output
*so
;
790 pa_core_assert_ref(c
);
795 if (!(n
= pa_tokenizer_get(t
, 1))) {
796 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
800 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
801 pa_strbuf_puts(buf
, "Failed to parse index.\n");
805 if (!(s
= pa_tokenizer_get(t
, 2))) {
806 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
810 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
811 pa_strbuf_puts(buf
, "No source output found with this index.\n");
815 p
= pa_proplist_from_string(s
);
817 pa_source_output_update_proplist(so
, PA_UPDATE_REPLACE
, p
);
824 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
830 pa_core_assert_ref(c
);
835 if (!(n
= pa_tokenizer_get(t
, 1))) {
836 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
840 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
841 pa_strbuf_puts(buf
, "Failed to parse index.\n");
845 if (!(v
= pa_tokenizer_get(t
, 2))) {
846 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
850 if ((mute
= pa_parse_boolean(v
)) < 0) {
851 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
855 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
856 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
860 pa_sink_input_set_mute(si
, mute
, TRUE
);
864 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
868 pa_core_assert_ref(c
);
873 if (!(n
= pa_tokenizer_get(t
, 1))) {
874 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
878 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
)))
879 pa_namereg_set_default_sink(c
, s
);
881 pa_strbuf_printf(buf
, "Sink %s does not exist.\n", n
);
886 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
890 pa_core_assert_ref(c
);
895 if (!(n
= pa_tokenizer_get(t
, 1))) {
896 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
900 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
)))
901 pa_namereg_set_default_source(c
, s
);
903 pa_strbuf_printf(buf
, "Source %s does not exist.\n", n
);
907 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
912 pa_core_assert_ref(c
);
917 if (!(n
= pa_tokenizer_get(t
, 1))) {
918 pa_strbuf_puts(buf
, "You need to specify a client by its index.\n");
922 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
923 pa_strbuf_puts(buf
, "Failed to parse index.\n");
927 if (!(client
= pa_idxset_get_by_index(c
->clients
, idx
))) {
928 pa_strbuf_puts(buf
, "No client found by this index.\n");
932 pa_client_kill(client
);
936 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
938 pa_sink_input
*sink_input
;
941 pa_core_assert_ref(c
);
946 if (!(n
= pa_tokenizer_get(t
, 1))) {
947 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
951 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
952 pa_strbuf_puts(buf
, "Failed to parse index.\n");
956 if (!(sink_input
= pa_idxset_get_by_index(c
->sink_inputs
, idx
))) {
957 pa_strbuf_puts(buf
, "No sink input found by this index.\n");
961 pa_sink_input_kill(sink_input
);
965 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
967 pa_source_output
*source_output
;
970 pa_core_assert_ref(c
);
975 if (!(n
= pa_tokenizer_get(t
, 1))) {
976 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
980 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
981 pa_strbuf_puts(buf
, "Failed to parse index.\n");
985 if (!(source_output
= pa_idxset_get_by_index(c
->source_outputs
, idx
))) {
986 pa_strbuf_puts(buf
, "No source output found by this index.\n");
990 pa_source_output_kill(source_output
);
994 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
997 pa_core_assert_ref(c
);
1002 pa_assert_se(s
= pa_scache_list_to_string(c
));
1003 pa_strbuf_puts(buf
, s
);
1009 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1010 const char *n
, *sink_name
;
1014 pa_core_assert_ref(c
);
1019 if (!(n
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1020 pa_strbuf_puts(buf
, "You need to specify a sample name and a sink name.\n");
1024 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1025 pa_strbuf_puts(buf
, "No sink by that name.\n");
1029 if (pa_scache_play_item(c
, n
, sink
, PA_VOLUME_NORM
, NULL
, &idx
) < 0) {
1030 pa_strbuf_puts(buf
, "Failed to play sample.\n");
1034 pa_strbuf_printf(buf
, "Playing on sink input #%i\n", idx
);
1039 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1042 pa_core_assert_ref(c
);
1047 if (!(n
= pa_tokenizer_get(t
, 1))) {
1048 pa_strbuf_puts(buf
, "You need to specify a sample name.\n");
1052 if (pa_scache_remove_item(c
, n
) < 0) {
1053 pa_strbuf_puts(buf
, "Failed to remove sample.\n");
1060 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1061 const char *fname
, *n
;
1064 pa_core_assert_ref(c
);
1069 if (!(fname
= pa_tokenizer_get(t
, 2)) || !(n
= pa_tokenizer_get(t
, 1))) {
1070 pa_strbuf_puts(buf
, "You need to specify a file name and a sample name.\n");
1074 if (strstr(pa_tokenizer_get(t
, 0), "lazy"))
1075 r
= pa_scache_add_file_lazy(c
, n
, fname
, NULL
);
1077 r
= pa_scache_add_file(c
, n
, fname
, NULL
);
1080 pa_strbuf_puts(buf
, "Failed to load sound file.\n");
1085 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1088 pa_core_assert_ref(c
);
1093 if (!(pname
= pa_tokenizer_get(t
, 1))) {
1094 pa_strbuf_puts(buf
, "You need to specify a path name.\n");
1098 if (pa_scache_add_directory_lazy(c
, pname
) < 0) {
1099 pa_strbuf_puts(buf
, "Failed to load directory.\n");
1106 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1107 const char *fname
, *sink_name
;
1110 pa_core_assert_ref(c
);
1115 if (!(fname
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1116 pa_strbuf_puts(buf
, "You need to specify a file name and a sink name.\n");
1120 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1121 pa_strbuf_puts(buf
, "No sink by that name.\n");
1126 return pa_play_file(sink
, fname
, NULL
);
1129 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1130 pa_core_assert_ref(c
);
1135 pa_shared_dump(c
, buf
);
1139 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1140 pa_core_assert_ref(c
);
1145 pa_mempool_vacuum(c
->mempool
);
1150 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1156 pa_core_assert_ref(c
);
1161 if (!(n
= pa_tokenizer_get(t
, 1))) {
1162 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
1166 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1167 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1171 if (!(k
= pa_tokenizer_get(t
, 2))) {
1172 pa_strbuf_puts(buf
, "You need to specify a sink.\n");
1176 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
1177 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
1181 if (!(sink
= pa_namereg_get(c
, k
, PA_NAMEREG_SINK
))) {
1182 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1186 if (pa_sink_input_move_to(si
, sink
, TRUE
) < 0) {
1187 pa_strbuf_puts(buf
, "Moved failed.\n");
1193 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1195 pa_source_output
*so
;
1199 pa_core_assert_ref(c
);
1204 if (!(n
= pa_tokenizer_get(t
, 1))) {
1205 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
1209 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1210 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1214 if (!(k
= pa_tokenizer_get(t
, 2))) {
1215 pa_strbuf_puts(buf
, "You need to specify a source.\n");
1219 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
1220 pa_strbuf_puts(buf
, "No source output found with this index.\n");
1224 if (!(source
= pa_namereg_get(c
, k
, PA_NAMEREG_SOURCE
))) {
1225 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1229 if (pa_source_output_move_to(so
, source
, TRUE
) < 0) {
1230 pa_strbuf_puts(buf
, "Moved failed.\n");
1236 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1241 pa_core_assert_ref(c
);
1246 if (!(n
= pa_tokenizer_get(t
, 1))) {
1247 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1251 if (!(m
= pa_tokenizer_get(t
, 2))) {
1252 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1256 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1257 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1261 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
1262 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1266 pa_sink_suspend(sink
, suspend
);
1270 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1275 pa_core_assert_ref(c
);
1280 if (!(n
= pa_tokenizer_get(t
, 1))) {
1281 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1285 if (!(m
= pa_tokenizer_get(t
, 2))) {
1286 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1290 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1291 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1295 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
1296 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1300 pa_source_suspend(source
, suspend
);
1304 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1309 pa_core_assert_ref(c
);
1314 if (!(m
= pa_tokenizer_get(t
, 1))) {
1315 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1319 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1320 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1324 ret
= - (pa_sink_suspend_all(c
, suspend
) < 0);
1325 if (pa_source_suspend_all(c
, suspend
) < 0)
1329 pa_strbuf_puts(buf
, "Failed to resume/suspend all sinks/sources.\n");
1334 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1338 pa_core_assert_ref(c
);
1343 if (!(m
= pa_tokenizer_get(t
, 1))) {
1344 pa_strbuf_puts(buf
, "You need to specify a log level (0..4).\n");
1348 if (pa_atou(m
, &level
) < 0 || level
>= PA_LOG_LEVEL_MAX
) {
1349 pa_strbuf_puts(buf
, "Failed to parse log level.\n");
1353 pa_log_set_level(level
);
1358 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1362 pa_core_assert_ref(c
);
1367 if (!(m
= pa_tokenizer_get(t
, 1))) {
1368 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1372 if ((b
= pa_parse_boolean(m
)) < 0) {
1373 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1377 pa_log_set_flags(PA_LOG_PRINT_META
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1382 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1386 pa_core_assert_ref(c
);
1391 if (!(m
= pa_tokenizer_get(t
, 1))) {
1392 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1396 if ((b
= pa_parse_boolean(m
)) < 0) {
1397 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1401 pa_log_set_flags(PA_LOG_PRINT_TIME
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1406 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1410 pa_core_assert_ref(c
);
1415 if (!(m
= pa_tokenizer_get(t
, 1))) {
1416 pa_strbuf_puts(buf
, "You need to specify a backtrace level.\n");
1420 if (pa_atou(m
, &nframes
) < 0 || nframes
>= 1000) {
1421 pa_strbuf_puts(buf
, "Failed to parse backtrace level.\n");
1425 pa_log_set_show_backtrace(nframes
);
1430 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1434 pa_core_assert_ref(c
);
1439 if (!(n
= pa_tokenizer_get(t
, 1))) {
1440 pa_strbuf_puts(buf
, "You need to specify a card either by its name or its index.\n");
1444 if (!(p
= pa_tokenizer_get(t
, 2))) {
1445 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1449 if (!(card
= pa_namereg_get(c
, n
, PA_NAMEREG_CARD
))) {
1450 pa_strbuf_puts(buf
, "No card found by this name or index.\n");
1454 if (pa_card_set_profile(card
, p
) < 0) {
1455 pa_strbuf_printf(buf
, "Failed to set card profile to '%s'.\n", p
);
1462 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1472 pa_core_assert_ref(c
);
1480 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime_r(&now
, txt
));
1482 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime(&now
));
1485 for (m
= pa_idxset_first(c
->modules
, &idx
); m
; m
= pa_idxset_next(c
->modules
, &idx
)) {
1487 pa_strbuf_printf(buf
, "load-module %s", m
->name
);
1490 pa_strbuf_printf(buf
, " %s", m
->argument
);
1492 pa_strbuf_puts(buf
, "\n");
1497 for (sink
= pa_idxset_first(c
->sinks
, &idx
); sink
; sink
= pa_idxset_next(c
->sinks
, &idx
)) {
1500 pa_strbuf_puts(buf
, "\n");
1504 pa_strbuf_printf(buf
, "set-sink-volume %s 0x%03x\n", sink
->name
, pa_cvolume_avg(pa_sink_get_volume(sink
, FALSE
)));
1505 pa_strbuf_printf(buf
, "set-sink-mute %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_mute(sink
, FALSE
)));
1506 pa_strbuf_printf(buf
, "suspend-sink %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_state(sink
) == PA_SINK_SUSPENDED
));
1509 for (source
= pa_idxset_first(c
->sources
, &idx
); source
; source
= pa_idxset_next(c
->sources
, &idx
)) {
1512 pa_strbuf_puts(buf
, "\n");
1516 pa_strbuf_printf(buf
, "set-source-volume %s 0x%03x\n", source
->name
, pa_cvolume_avg(pa_source_get_volume(source
, FALSE
)));
1517 pa_strbuf_printf(buf
, "set-source-mute %s %s\n", source
->name
, pa_yes_no(pa_source_get_mute(source
, FALSE
)));
1518 pa_strbuf_printf(buf
, "suspend-source %s %s\n", source
->name
, pa_yes_no(pa_source_get_state(source
) == PA_SOURCE_SUSPENDED
));
1521 for (card
= pa_idxset_first(c
->cards
, &idx
); card
; card
= pa_idxset_next(c
->cards
, &idx
)) {
1524 pa_strbuf_puts(buf
, "\n");
1528 if (card
->active_profile
)
1529 pa_strbuf_printf(buf
, "set-card-profile %s %s\n", card
->name
, card
->active_profile
->name
);
1534 if ((sink
= pa_namereg_get_default_sink(c
))) {
1536 pa_strbuf_puts(buf
, "\n");
1539 pa_strbuf_printf(buf
, "set-default-sink %s\n", sink
->name
);
1542 if ((source
= pa_namereg_get_default_source(c
))) {
1544 pa_strbuf_puts(buf
, "\n");
1547 pa_strbuf_printf(buf
, "set-default-source %s\n", source
->name
);
1550 pa_strbuf_puts(buf
, "\n### EOF\n");
1555 int pa_cli_command_execute_line_stateful(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
, int *ifstate
) {
1562 cs
= s
+strspn(s
, whitespace
);
1564 if (*cs
== '#' || !*cs
)
1566 else if (*cs
== '.') {
1567 if (!strcmp(cs
, META_ELSE
)) {
1568 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1569 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1571 } else if (*ifstate
== IFSTATE_TRUE
)
1572 *ifstate
= IFSTATE_FALSE
;
1574 *ifstate
= IFSTATE_TRUE
;
1576 } else if (!strcmp(cs
, META_ENDIF
)) {
1577 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1578 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1581 *ifstate
= IFSTATE_NONE
;
1584 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1586 if (!strcmp(cs
, META_FAIL
))
1588 else if (!strcmp(cs
, META_NOFAIL
))
1592 l
= strcspn(cs
, whitespace
);
1594 if (l
== sizeof(META_INCLUDE
)-1 && !strncmp(cs
, META_INCLUDE
, l
)) {
1595 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1596 if (pa_cli_command_execute_file(c
, filename
, buf
, fail
) < 0)
1599 } else if (l
== sizeof(META_IFEXISTS
)-1 && !strncmp(cs
, META_IFEXISTS
, l
)) {
1601 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1603 } else if (*ifstate
!= IFSTATE_NONE
) {
1604 pa_strbuf_printf(buf
, "Nested %s commands not supported\n", cs
);
1607 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1609 /* Search DL_SEARCH_PATH unless the filename is absolute */
1610 if (filename
[0] == PA_PATH_SEP_CHAR
) {
1612 *ifstate
= access(filename
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1613 pa_log_debug("Checking for existance of '%s': %s", filename
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1616 const char *paths
, *state
= NULL
;
1619 if (!(paths
= lt_dlgetsearchpath()))
1622 while ((p
= pa_split(paths
, ":", &state
))) {
1625 pathname
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", p
, filename
);
1628 *ifstate
= access(pathname
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1629 pa_log_debug("Checking for existance of '%s': %s", pathname
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1633 if (*ifstate
== IFSTATE_TRUE
)
1640 pa_strbuf_printf(buf
, "Invalid meta command: %s\n", cs
);
1641 if (*fail
) return -1;
1645 const struct command
*command
;
1649 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1652 l
= strcspn(cs
, whitespace
);
1654 for (command
= commands
; command
->name
; command
++)
1655 if (strlen(command
->name
) == l
&& !strncmp(cs
, command
->name
, l
)) {
1657 pa_tokenizer
*t
= pa_tokenizer_new(cs
, command
->args
);
1659 ret
= command
->proc(c
, t
, buf
, fail
);
1660 pa_tokenizer_free(t
);
1663 if (ret
< 0 && *fail
)
1670 pa_strbuf_printf(buf
, "Unknown command: %s\n", cs
);
1679 int pa_cli_command_execute_line(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1680 return pa_cli_command_execute_line_stateful(c
, s
, buf
, fail
, NULL
);
1683 int pa_cli_command_execute_file_stream(pa_core
*c
, FILE *f
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1685 int ifstate
= IFSTATE_NONE
;
1687 pa_bool_t _fail
= TRUE
;
1696 while (fgets(line
, sizeof(line
), f
)) {
1699 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
)
1710 int pa_cli_command_execute_file(pa_core
*c
, const char *fn
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1713 pa_bool_t _fail
= TRUE
;
1722 if (!(f
= fopen(fn
, "r"))) {
1723 pa_strbuf_printf(buf
, "open('%s') failed: %s\n", fn
, pa_cstrerror(errno
));
1729 ret
= pa_cli_command_execute_file_stream(c
, f
, buf
, fail
);
1740 int pa_cli_command_execute(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1742 int ifstate
= IFSTATE_NONE
;
1743 pa_bool_t _fail
= TRUE
;
1754 size_t l
= strcspn(p
, linebreak
);
1755 char *line
= pa_xstrndup(p
, l
);
1757 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
) {
1764 p
+= strspn(p
, linebreak
);