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
38 #include <pulse/xmalloc.h>
39 #include <pulse/error.h>
41 #include <pulsecore/module.h>
42 #include <pulsecore/sink.h>
43 #include <pulsecore/source.h>
44 #include <pulsecore/client.h>
45 #include <pulsecore/sink-input.h>
46 #include <pulsecore/source-output.h>
47 #include <pulsecore/tokenizer.h>
48 #include <pulsecore/strbuf.h>
49 #include <pulsecore/namereg.h>
50 #include <pulsecore/cli-text.h>
51 #include <pulsecore/core-scache.h>
52 #include <pulsecore/sound-file.h>
53 #include <pulsecore/play-memchunk.h>
54 #include <pulsecore/sound-file-stream.h>
55 #include <pulsecore/shared.h>
56 #include <pulsecore/core-util.h>
57 #include <pulsecore/core-error.h>
58 #include <pulsecore/modinfo.h>
59 #include <pulsecore/dynarray.h>
61 #include "cli-command.h"
65 int (*proc
) (pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
70 #define META_INCLUDE ".include"
71 #define META_FAIL ".fail"
72 #define META_NOFAIL ".nofail"
73 #define META_IFEXISTS ".ifexists"
74 #define META_ELSE ".else"
75 #define META_ENDIF ".endif"
83 /* Prototypes for all available commands */
84 static int pa_cli_command_exit(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
85 static int pa_cli_command_help(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
86 static int pa_cli_command_modules(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
87 static int pa_cli_command_clients(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
88 static int pa_cli_command_cards(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
89 static int pa_cli_command_sinks(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
90 static int pa_cli_command_sources(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
91 static int pa_cli_command_sink_inputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
92 static int pa_cli_command_source_outputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
93 static int pa_cli_command_stat(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
94 static int pa_cli_command_info(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
95 static int pa_cli_command_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
96 static int pa_cli_command_unload(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
97 static int pa_cli_command_describe(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
98 static int pa_cli_command_sink_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
99 static int pa_cli_command_sink_input_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
100 static int pa_cli_command_source_output_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
101 static int pa_cli_command_source_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
102 static int pa_cli_command_sink_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
103 static int pa_cli_command_source_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
104 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
105 static int pa_cli_command_source_output_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
106 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
107 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
108 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
109 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
110 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
111 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
112 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
113 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
114 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
115 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
116 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
117 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
118 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
119 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
120 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
121 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
122 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
123 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
124 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
125 static int pa_cli_command_log_target(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
126 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
127 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
128 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
129 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
130 static int pa_cli_command_update_sink_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
131 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
132 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
133 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
134 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
135 static int pa_cli_command_sink_port(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
136 static int pa_cli_command_source_port(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
137 static int pa_cli_command_dump_volumes(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
);
139 /* A method table for all available commands */
141 static const struct command commands
[] = {
142 { "help", pa_cli_command_help
, "Show this help", 1 },
143 { "list-modules", pa_cli_command_modules
, "List loaded modules", 1 },
144 { "list-cards", pa_cli_command_cards
, "List cards", 1 },
145 { "list-sinks", pa_cli_command_sinks
, "List loaded sinks", 1 },
146 { "list-sources", pa_cli_command_sources
, "List loaded sources", 1 },
147 { "list-clients", pa_cli_command_clients
, "List loaded clients", 1 },
148 { "list-sink-inputs", pa_cli_command_sink_inputs
, "List sink inputs", 1 },
149 { "list-source-outputs", pa_cli_command_source_outputs
, "List source outputs", 1 },
150 { "stat", pa_cli_command_stat
, "Show memory block statistics", 1 },
151 { "info", pa_cli_command_info
, "Show comprehensive status", 1 },
152 { "ls", pa_cli_command_info
, NULL
, 1 },
153 { "list", pa_cli_command_info
, NULL
, 1 },
154 { "load-module", pa_cli_command_load
, "Load a module (args: name, arguments)", 3},
155 { "unload-module", pa_cli_command_unload
, "Unload a module (args: index)", 2},
156 { "describe-module", pa_cli_command_describe
, "Describe a module (arg: name)", 2},
157 { "set-sink-volume", pa_cli_command_sink_volume
, "Set the volume of a sink (args: index|name, volume)", 3},
158 { "set-source-volume", pa_cli_command_source_volume
, "Set the volume of a source (args: index|name, volume)", 3},
159 { "set-sink-mute", pa_cli_command_sink_mute
, "Set the mute switch of a sink (args: index|name, bool)", 3},
160 { "set-source-mute", pa_cli_command_source_mute
, "Set the mute switch of a source (args: index|name, bool)", 3},
161 { "set-sink-input-volume", pa_cli_command_sink_input_volume
, "Set the volume of a sink input (args: index, volume)", 3},
162 { "set-source-output-volume",pa_cli_command_source_output_volume
,"Set the volume of a source output (args: index, volume)", 3},
163 { "set-sink-input-mute", pa_cli_command_sink_input_mute
, "Set the mute switch of a sink input (args: index, bool)", 3},
164 { "set-source-output-mute", pa_cli_command_source_output_mute
, "Set the mute switch of a source output (args: index, bool)", 3},
165 { "set-default-sink", pa_cli_command_sink_default
, "Set the default sink (args: index|name)", 2},
166 { "set-default-source", pa_cli_command_source_default
, "Set the default source (args: index|name)", 2},
167 { "set-card-profile", pa_cli_command_card_profile
, "Change the profile of a card (args: index|name, profile-name)", 3},
168 { "set-sink-port", pa_cli_command_sink_port
, "Change the port of a sink (args: index|name, port-name)", 3},
169 { "set-source-port", pa_cli_command_source_port
, "Change the port of a source (args: index|name, port-name)", 3},
170 { "suspend-sink", pa_cli_command_suspend_sink
, "Suspend sink (args: index|name, bool)", 3},
171 { "suspend-source", pa_cli_command_suspend_source
, "Suspend source (args: index|name, bool)", 3},
172 { "suspend", pa_cli_command_suspend
, "Suspend all sinks and all sources (args: bool)", 2},
173 { "move-sink-input", pa_cli_command_move_sink_input
, "Move sink input to another sink (args: index, sink)", 3},
174 { "move-source-output", pa_cli_command_move_source_output
, "Move source output to another source (args: index, source)", 3},
175 { "update-sink-proplist", pa_cli_command_update_sink_proplist
, "Update the properties of a sink (args: index|name, properties)", 3},
176 { "update-source-proplist", pa_cli_command_update_source_proplist
, "Update the properties of a source (args: index|name, properties)", 3},
177 { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist
, "Update the properties of a sink input (args: index, properties)", 3},
178 { "update-source-output-proplist", pa_cli_command_update_source_output_proplist
, "Update the properties of a source output (args: index, properties)", 3},
179 { "list-samples", pa_cli_command_scache_list
, "List all entries in the sample cache", 1},
180 { "play-sample", pa_cli_command_scache_play
, "Play a sample from the sample cache (args: name, sink|index)", 3},
181 { "remove-sample", pa_cli_command_scache_remove
, "Remove a sample from the sample cache (args: name)", 2},
182 { "load-sample", pa_cli_command_scache_load
, "Load a sound file into the sample cache (args: name, filename)", 3},
183 { "load-sample-lazy", pa_cli_command_scache_load
, "Lazily load a sound file into the sample cache (args: name, filename)", 3},
184 { "load-sample-dir-lazy", pa_cli_command_scache_load_dir
, "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
185 { "kill-client", pa_cli_command_kill_client
, "Kill a client (args: index)", 2},
186 { "kill-sink-input", pa_cli_command_kill_sink_input
, "Kill a sink input (args: index)", 2},
187 { "kill-source-output", pa_cli_command_kill_source_output
, "Kill a source output (args: index)", 2},
188 { "set-log-target", pa_cli_command_log_target
, "Change the log target (args: null,auto,syslog,stderr,file:PATH)", 2},
189 { "set-log-level", pa_cli_command_log_level
, "Change the log level (args: numeric level)", 2},
190 { "set-log-meta", pa_cli_command_log_meta
, "Show source code location in log messages (args: bool)", 2},
191 { "set-log-time", pa_cli_command_log_time
, "Show timestamps in log messages (args: bool)", 2},
192 { "set-log-backtrace", pa_cli_command_log_backtrace
, "Show backtrace in log messages (args: frames)", 2},
193 { "play-file", pa_cli_command_play_file
, "Play a sound file (args: filename, sink|index)", 3},
194 { "dump", pa_cli_command_dump
, "Dump daemon configuration", 1},
195 { "dump-volumes", pa_cli_command_dump_volumes
, "Debug: Show the state of all volumes", 1 },
196 { "shared", pa_cli_command_list_shared_props
, "Debug: Show shared properties", 1},
197 { "exit", pa_cli_command_exit
, "Terminate the daemon", 1 },
198 { "vacuum", pa_cli_command_vacuum
, NULL
, 1},
199 { NULL
, NULL
, NULL
, 0 }
202 static const char whitespace
[] = " \t\n\r";
203 static const char linebreak
[] = "\n\r";
205 static uint32_t parse_index(const char *n
) {
208 if (pa_atou(n
, &idx
) < 0)
209 return (uint32_t) PA_IDXSET_INVALID
;
214 static int pa_cli_command_exit(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
215 pa_core_assert_ref(c
);
220 if (pa_core_exit(c
, FALSE
, 0) < 0)
221 pa_strbuf_puts(buf
, "Not allowed to terminate daemon.\n");
226 static int pa_cli_command_help(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
227 const struct command
*command
;
229 pa_core_assert_ref(c
);
234 pa_strbuf_puts(buf
, "Available commands:\n");
236 for (command
= commands
; command
->name
; command
++)
238 pa_strbuf_printf(buf
, " %-25s %s\n", command
->name
, command
->help
);
242 static int pa_cli_command_modules(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
245 pa_core_assert_ref(c
);
250 pa_assert_se(s
= pa_module_list_to_string(c
));
251 pa_strbuf_puts(buf
, s
);
256 static int pa_cli_command_clients(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
259 pa_core_assert_ref(c
);
264 pa_assert_se(s
= pa_client_list_to_string(c
));
265 pa_strbuf_puts(buf
, s
);
270 static int pa_cli_command_cards(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
273 pa_core_assert_ref(c
);
278 pa_assert_se(s
= pa_card_list_to_string(c
));
279 pa_strbuf_puts(buf
, s
);
284 static int pa_cli_command_sinks(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
287 pa_core_assert_ref(c
);
292 pa_assert_se(s
= pa_sink_list_to_string(c
));
293 pa_strbuf_puts(buf
, s
);
298 static int pa_cli_command_sources(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
301 pa_core_assert_ref(c
);
306 pa_assert_se(s
= pa_source_list_to_string(c
));
307 pa_strbuf_puts(buf
, s
);
312 static int pa_cli_command_sink_inputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
315 pa_core_assert_ref(c
);
320 pa_assert_se(s
= pa_sink_input_list_to_string(c
));
321 pa_strbuf_puts(buf
, s
);
326 static int pa_cli_command_source_outputs(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
329 pa_core_assert_ref(c
);
334 pa_assert_se(s
= pa_source_output_list_to_string(c
));
335 pa_strbuf_puts(buf
, s
);
340 static int pa_cli_command_stat(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
341 char ss
[PA_SAMPLE_SPEC_SNPRINT_MAX
];
342 char cm
[PA_CHANNEL_MAP_SNPRINT_MAX
];
343 char bytes
[PA_BYTES_SNPRINT_MAX
];
344 const pa_mempool_stat
*mstat
;
347 pa_source
*def_source
;
349 static const char* const type_table
[PA_MEMBLOCK_TYPE_MAX
] = {
350 [PA_MEMBLOCK_POOL
] = "POOL",
351 [PA_MEMBLOCK_POOL_EXTERNAL
] = "POOL_EXTERNAL",
352 [PA_MEMBLOCK_APPENDED
] = "APPENDED",
353 [PA_MEMBLOCK_USER
] = "USER",
354 [PA_MEMBLOCK_FIXED
] = "FIXED",
355 [PA_MEMBLOCK_IMPORTED
] = "IMPORTED",
358 pa_core_assert_ref(c
);
363 mstat
= pa_mempool_get_stat(c
->mempool
);
365 pa_strbuf_printf(buf
, "Memory blocks currently allocated: %u, size: %s.\n",
366 (unsigned) pa_atomic_load(&mstat
->n_allocated
),
367 pa_bytes_snprint(bytes
, sizeof(bytes
), (unsigned) pa_atomic_load(&mstat
->allocated_size
)));
369 pa_strbuf_printf(buf
, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
370 (unsigned) pa_atomic_load(&mstat
->n_accumulated
),
371 pa_bytes_snprint(bytes
, sizeof(bytes
), (unsigned) pa_atomic_load(&mstat
->accumulated_size
)));
373 pa_strbuf_printf(buf
, "Memory blocks imported from other processes: %u, size: %s.\n",
374 (unsigned) pa_atomic_load(&mstat
->n_imported
),
375 pa_bytes_snprint(bytes
, sizeof(bytes
), (unsigned) pa_atomic_load(&mstat
->imported_size
)));
377 pa_strbuf_printf(buf
, "Memory blocks exported to other processes: %u, size: %s.\n",
378 (unsigned) pa_atomic_load(&mstat
->n_exported
),
379 pa_bytes_snprint(bytes
, sizeof(bytes
), (unsigned) pa_atomic_load(&mstat
->exported_size
)));
381 pa_strbuf_printf(buf
, "Total sample cache size: %s.\n",
382 pa_bytes_snprint(bytes
, sizeof(bytes
), (unsigned) pa_scache_total_size(c
)));
384 pa_strbuf_printf(buf
, "Default sample spec: %s\n",
385 pa_sample_spec_snprint(ss
, sizeof(ss
), &c
->default_sample_spec
));
387 pa_strbuf_printf(buf
, "Default channel map: %s\n",
388 pa_channel_map_snprint(cm
, sizeof(cm
), &c
->default_channel_map
));
390 def_sink
= pa_namereg_get_default_sink(c
);
391 def_source
= pa_namereg_get_default_source(c
);
392 pa_strbuf_printf(buf
, "Default sink name: %s\n"
393 "Default source name: %s\n",
394 def_sink
? def_sink
->name
: "none",
395 def_source
? def_source
->name
: "none");
397 for (k
= 0; k
< PA_MEMBLOCK_TYPE_MAX
; k
++)
398 pa_strbuf_printf(buf
,
399 "Memory blocks of type %s: %u allocated/%u accumulated.\n",
401 (unsigned) pa_atomic_load(&mstat
->n_allocated_by_type
[k
]),
402 (unsigned) pa_atomic_load(&mstat
->n_accumulated_by_type
[k
]));
407 static int pa_cli_command_info(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
408 pa_core_assert_ref(c
);
413 pa_cli_command_stat(c
, t
, buf
, fail
);
414 pa_cli_command_modules(c
, t
, buf
, fail
);
415 pa_cli_command_sinks(c
, t
, buf
, fail
);
416 pa_cli_command_sources(c
, t
, buf
, fail
);
417 pa_cli_command_clients(c
, t
, buf
, fail
);
418 pa_cli_command_cards(c
, t
, buf
, fail
);
419 pa_cli_command_sink_inputs(c
, t
, buf
, fail
);
420 pa_cli_command_source_outputs(c
, t
, buf
, fail
);
421 pa_cli_command_scache_list(c
, t
, buf
, fail
);
425 static int pa_cli_command_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
428 pa_core_assert_ref(c
);
433 if (!(name
= pa_tokenizer_get(t
, 1))) {
434 pa_strbuf_puts(buf
, "You need to specify the module name and optionally arguments.\n");
438 if (!pa_module_load(c
, name
, pa_tokenizer_get(t
, 2))) {
439 pa_strbuf_puts(buf
, "Module load failed.\n");
446 static int pa_cli_command_unload(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
452 pa_core_assert_ref(c
);
457 if (!(i
= pa_tokenizer_get(t
, 1))) {
458 pa_strbuf_puts(buf
, "You need to specify the module index.\n");
462 idx
= (uint32_t) strtoul(i
, &e
, 10);
463 if (*e
|| !(m
= pa_idxset_get_by_index(c
->modules
, idx
))) {
464 pa_strbuf_puts(buf
, "Invalid module index.\n");
468 pa_module_unload_request(m
, FALSE
);
472 static int pa_cli_command_describe(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
476 pa_core_assert_ref(c
);
481 if (!(name
= pa_tokenizer_get(t
, 1))) {
482 pa_strbuf_puts(buf
, "You need to specify the module name.\n");
486 if ((i
= pa_modinfo_get_by_name(name
))) {
488 pa_strbuf_printf(buf
, "Name: %s\n", name
);
490 if (!i
->description
&& !i
->version
&& !i
->author
&& !i
->usage
)
491 pa_strbuf_printf(buf
, "No module information available\n");
494 pa_strbuf_printf(buf
, "Version: %s\n", i
->version
);
496 pa_strbuf_printf(buf
, "Description: %s\n", i
->description
);
498 pa_strbuf_printf(buf
, "Author: %s\n", i
->author
);
500 pa_strbuf_printf(buf
, "Usage: %s\n", i
->usage
);
501 pa_strbuf_printf(buf
, "Load Once: %s\n", pa_yes_no(i
->load_once
));
503 pa_strbuf_printf(buf
, "Warning, deprecated: %s\n", i
->deprecated
);
508 pa_strbuf_puts(buf
, "Failed to open module.\n");
513 static int pa_cli_command_sink_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
519 pa_core_assert_ref(c
);
524 if (!(n
= pa_tokenizer_get(t
, 1))) {
525 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
529 if (!(v
= pa_tokenizer_get(t
, 2))) {
530 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
534 if (pa_atou(v
, &volume
) < 0) {
535 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
539 if (!PA_VOLUME_IS_VALID(volume
)) {
540 pa_strbuf_puts(buf
, "Volume outside permissible range.\n");
544 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
545 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
549 pa_cvolume_set(&cvolume
, 1, volume
);
550 pa_sink_set_volume(sink
, &cvolume
, TRUE
, TRUE
);
554 static int pa_cli_command_sink_input_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
561 pa_core_assert_ref(c
);
566 if (!(n
= pa_tokenizer_get(t
, 1))) {
567 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
571 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
572 pa_strbuf_puts(buf
, "Failed to parse index.\n");
576 if (!(v
= pa_tokenizer_get(t
, 2))) {
577 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
581 if (pa_atou(v
, &volume
) < 0) {
582 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
586 if (!PA_VOLUME_IS_VALID(volume
)) {
587 pa_strbuf_puts(buf
, "Volume outside permissible range.\n");
591 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, idx
))) {
592 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
596 if (!si
->volume_writable
) {
597 pa_strbuf_puts(buf
, "This sink input's volume can't be changed.\n");
601 pa_cvolume_set(&cvolume
, 1, volume
);
602 pa_sink_input_set_volume(si
, &cvolume
, TRUE
, TRUE
);
606 static int pa_cli_command_source_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
612 pa_core_assert_ref(c
);
617 if (!(n
= pa_tokenizer_get(t
, 1))) {
618 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
622 if (!(v
= pa_tokenizer_get(t
, 2))) {
623 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
627 if (pa_atou(v
, &volume
) < 0) {
628 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
632 if (!PA_VOLUME_IS_VALID(volume
)) {
633 pa_strbuf_puts(buf
, "Volume outside permissible range.\n");
637 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
638 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
642 pa_cvolume_set(&cvolume
, 1, volume
);
643 pa_source_set_volume(source
, &cvolume
, TRUE
, TRUE
);
647 static int pa_cli_command_source_output_volume(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
649 pa_source_output
*so
;
654 pa_core_assert_ref(c
);
659 if (!(n
= pa_tokenizer_get(t
, 1))) {
660 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
664 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
665 pa_strbuf_puts(buf
, "Failed to parse index.\n");
669 if (!(v
= pa_tokenizer_get(t
, 2))) {
670 pa_strbuf_puts(buf
, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
674 if (pa_atou(v
, &volume
) < 0) {
675 pa_strbuf_puts(buf
, "Failed to parse volume.\n");
679 if (!PA_VOLUME_IS_VALID(volume
)) {
680 pa_strbuf_puts(buf
, "Volume outside permissible range.\n");
684 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, idx
))) {
685 pa_strbuf_puts(buf
, "No source output found with this index.\n");
689 if (!so
->volume_writable
) {
690 pa_strbuf_puts(buf
, "This source output's volume can't be changed.\n");
694 pa_cvolume_set(&cvolume
, 1, volume
);
695 pa_source_output_set_volume(so
, &cvolume
, TRUE
, TRUE
);
699 static int pa_cli_command_sink_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
704 pa_core_assert_ref(c
);
709 if (!(n
= pa_tokenizer_get(t
, 1))) {
710 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
714 if (!(m
= pa_tokenizer_get(t
, 2))) {
715 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
719 if ((mute
= pa_parse_boolean(m
)) < 0) {
720 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
724 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
725 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
729 pa_sink_set_mute(sink
, mute
, TRUE
);
733 static int pa_cli_command_source_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
738 pa_core_assert_ref(c
);
743 if (!(n
= pa_tokenizer_get(t
, 1))) {
744 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
748 if (!(m
= pa_tokenizer_get(t
, 2))) {
749 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
753 if ((mute
= pa_parse_boolean(m
)) < 0) {
754 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
758 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
759 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
763 pa_source_set_mute(source
, mute
, TRUE
);
767 static int pa_cli_command_update_sink_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
772 pa_core_assert_ref(c
);
777 if (!(n
= pa_tokenizer_get(t
, 1))) {
778 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
782 if (!(s
= pa_tokenizer_get(t
, 2))) {
783 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
787 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
788 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
792 if (!(p
= pa_proplist_from_string(s
))) {
793 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
797 pa_sink_update_proplist(sink
, PA_UPDATE_REPLACE
, p
);
804 static int pa_cli_command_update_source_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
809 pa_core_assert_ref(c
);
814 if (!(n
= pa_tokenizer_get(t
, 1))) {
815 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
819 if (!(s
= pa_tokenizer_get(t
, 2))) {
820 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
824 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
825 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
829 if (!(p
= pa_proplist_from_string(s
))) {
830 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
834 pa_source_update_proplist(source
, PA_UPDATE_REPLACE
, p
);
841 static int pa_cli_command_update_sink_input_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
847 pa_core_assert_ref(c
);
852 if (!(n
= pa_tokenizer_get(t
, 1))) {
853 pa_strbuf_puts(buf
, "You need to specify a sink input either by index.\n");
857 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
858 pa_strbuf_puts(buf
, "Failed to parse index.\n");
862 if (!(s
= pa_tokenizer_get(t
, 2))) {
863 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
867 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
868 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
872 if (!(p
= pa_proplist_from_string(s
))) {
873 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
877 pa_sink_input_update_proplist(si
, PA_UPDATE_REPLACE
, p
);
884 static int pa_cli_command_update_source_output_proplist(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
886 pa_source_output
*so
;
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 output by its index.\n");
900 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
901 pa_strbuf_puts(buf
, "Failed to parse index.\n");
905 if (!(s
= pa_tokenizer_get(t
, 2))) {
906 pa_strbuf_puts(buf
, "You need to specify a \"key=value\" argument.\n");
910 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
911 pa_strbuf_puts(buf
, "No source output found with this index.\n");
915 if (!(p
= pa_proplist_from_string(s
))) {
916 pa_strbuf_puts(buf
, "Failed to parse proplist.\n");
920 pa_source_output_update_proplist(so
, PA_UPDATE_REPLACE
, p
);
927 static int pa_cli_command_sink_input_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
933 pa_core_assert_ref(c
);
938 if (!(n
= pa_tokenizer_get(t
, 1))) {
939 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
943 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
944 pa_strbuf_puts(buf
, "Failed to parse index.\n");
948 if (!(v
= pa_tokenizer_get(t
, 2))) {
949 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
953 if ((mute
= pa_parse_boolean(v
)) < 0) {
954 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
958 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
959 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
963 pa_sink_input_set_mute(si
, mute
, TRUE
);
967 static int pa_cli_command_source_output_mute(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
969 pa_source_output
*so
;
973 pa_core_assert_ref(c
);
978 if (!(n
= pa_tokenizer_get(t
, 1))) {
979 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
983 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
984 pa_strbuf_puts(buf
, "Failed to parse index.\n");
988 if (!(v
= pa_tokenizer_get(t
, 2))) {
989 pa_strbuf_puts(buf
, "You need to specify a mute switch setting (0/1).\n");
993 if ((mute
= pa_parse_boolean(v
)) < 0) {
994 pa_strbuf_puts(buf
, "Failed to parse mute switch.\n");
998 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
999 pa_strbuf_puts(buf
, "No source output found with this index.\n");
1003 pa_source_output_set_mute(so
, mute
, TRUE
);
1007 static int pa_cli_command_sink_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1011 pa_core_assert_ref(c
);
1016 if (!(n
= pa_tokenizer_get(t
, 1))) {
1017 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1021 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
)))
1022 pa_namereg_set_default_sink(c
, s
);
1024 pa_strbuf_printf(buf
, "Sink %s does not exist.\n", n
);
1029 static int pa_cli_command_source_default(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1033 pa_core_assert_ref(c
);
1038 if (!(n
= pa_tokenizer_get(t
, 1))) {
1039 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1043 if ((s
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
)))
1044 pa_namereg_set_default_source(c
, s
);
1046 pa_strbuf_printf(buf
, "Source %s does not exist.\n", n
);
1050 static int pa_cli_command_kill_client(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1055 pa_core_assert_ref(c
);
1060 if (!(n
= pa_tokenizer_get(t
, 1))) {
1061 pa_strbuf_puts(buf
, "You need to specify a client by its index.\n");
1065 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1066 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1070 if (!(client
= pa_idxset_get_by_index(c
->clients
, idx
))) {
1071 pa_strbuf_puts(buf
, "No client found by this index.\n");
1075 pa_client_kill(client
);
1079 static int pa_cli_command_kill_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1081 pa_sink_input
*sink_input
;
1084 pa_core_assert_ref(c
);
1089 if (!(n
= pa_tokenizer_get(t
, 1))) {
1090 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
1094 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1095 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1099 if (!(sink_input
= pa_idxset_get_by_index(c
->sink_inputs
, idx
))) {
1100 pa_strbuf_puts(buf
, "No sink input found by this index.\n");
1104 pa_sink_input_kill(sink_input
);
1108 static int pa_cli_command_kill_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1110 pa_source_output
*source_output
;
1113 pa_core_assert_ref(c
);
1118 if (!(n
= pa_tokenizer_get(t
, 1))) {
1119 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
1123 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1124 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1128 if (!(source_output
= pa_idxset_get_by_index(c
->source_outputs
, idx
))) {
1129 pa_strbuf_puts(buf
, "No source output found by this index.\n");
1133 pa_source_output_kill(source_output
);
1137 static int pa_cli_command_scache_list(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1140 pa_core_assert_ref(c
);
1145 pa_assert_se(s
= pa_scache_list_to_string(c
));
1146 pa_strbuf_puts(buf
, s
);
1152 static int pa_cli_command_scache_play(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1153 const char *n
, *sink_name
;
1157 pa_core_assert_ref(c
);
1162 if (!(n
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1163 pa_strbuf_puts(buf
, "You need to specify a sample name and a sink name.\n");
1167 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1168 pa_strbuf_puts(buf
, "No sink by that name.\n");
1172 if (pa_scache_play_item(c
, n
, sink
, PA_VOLUME_NORM
, NULL
, &idx
) < 0) {
1173 pa_strbuf_puts(buf
, "Failed to play sample.\n");
1177 pa_strbuf_printf(buf
, "Playing on sink input #%i\n", idx
);
1182 static int pa_cli_command_scache_remove(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1185 pa_core_assert_ref(c
);
1190 if (!(n
= pa_tokenizer_get(t
, 1))) {
1191 pa_strbuf_puts(buf
, "You need to specify a sample name.\n");
1195 if (pa_scache_remove_item(c
, n
) < 0) {
1196 pa_strbuf_puts(buf
, "Failed to remove sample.\n");
1203 static int pa_cli_command_scache_load(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1204 const char *fname
, *n
;
1207 pa_core_assert_ref(c
);
1212 if (!(fname
= pa_tokenizer_get(t
, 2)) || !(n
= pa_tokenizer_get(t
, 1))) {
1213 pa_strbuf_puts(buf
, "You need to specify a file name and a sample name.\n");
1217 if (strstr(pa_tokenizer_get(t
, 0), "lazy"))
1218 r
= pa_scache_add_file_lazy(c
, n
, fname
, NULL
);
1220 r
= pa_scache_add_file(c
, n
, fname
, NULL
);
1223 pa_strbuf_puts(buf
, "Failed to load sound file.\n");
1228 static int pa_cli_command_scache_load_dir(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1231 pa_core_assert_ref(c
);
1236 if (!(pname
= pa_tokenizer_get(t
, 1))) {
1237 pa_strbuf_puts(buf
, "You need to specify a path name.\n");
1241 if (pa_scache_add_directory_lazy(c
, pname
) < 0) {
1242 pa_strbuf_puts(buf
, "Failed to load directory.\n");
1249 static int pa_cli_command_play_file(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1250 const char *fname
, *sink_name
;
1253 pa_core_assert_ref(c
);
1258 if (!(fname
= pa_tokenizer_get(t
, 1)) || !(sink_name
= pa_tokenizer_get(t
, 2))) {
1259 pa_strbuf_puts(buf
, "You need to specify a file name and a sink name.\n");
1263 if (!(sink
= pa_namereg_get(c
, sink_name
, PA_NAMEREG_SINK
))) {
1264 pa_strbuf_puts(buf
, "No sink by that name.\n");
1269 return pa_play_file(sink
, fname
, NULL
);
1272 static int pa_cli_command_list_shared_props(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1273 pa_core_assert_ref(c
);
1278 pa_shared_dump(c
, buf
);
1282 static int pa_cli_command_vacuum(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1283 pa_core_assert_ref(c
);
1288 pa_mempool_vacuum(c
->mempool
);
1293 static int pa_cli_command_move_sink_input(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1299 pa_core_assert_ref(c
);
1304 if (!(n
= pa_tokenizer_get(t
, 1))) {
1305 pa_strbuf_puts(buf
, "You need to specify a sink input by its index.\n");
1309 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1310 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1314 if (!(k
= pa_tokenizer_get(t
, 2))) {
1315 pa_strbuf_puts(buf
, "You need to specify a sink.\n");
1319 if (!(si
= pa_idxset_get_by_index(c
->sink_inputs
, (uint32_t) idx
))) {
1320 pa_strbuf_puts(buf
, "No sink input found with this index.\n");
1324 if (!(sink
= pa_namereg_get(c
, k
, PA_NAMEREG_SINK
))) {
1325 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1329 if (pa_sink_input_move_to(si
, sink
, TRUE
) < 0) {
1330 pa_strbuf_puts(buf
, "Moved failed.\n");
1336 static int pa_cli_command_move_source_output(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1338 pa_source_output
*so
;
1342 pa_core_assert_ref(c
);
1347 if (!(n
= pa_tokenizer_get(t
, 1))) {
1348 pa_strbuf_puts(buf
, "You need to specify a source output by its index.\n");
1352 if ((idx
= parse_index(n
)) == PA_IDXSET_INVALID
) {
1353 pa_strbuf_puts(buf
, "Failed to parse index.\n");
1357 if (!(k
= pa_tokenizer_get(t
, 2))) {
1358 pa_strbuf_puts(buf
, "You need to specify a source.\n");
1362 if (!(so
= pa_idxset_get_by_index(c
->source_outputs
, (uint32_t) idx
))) {
1363 pa_strbuf_puts(buf
, "No source output found with this index.\n");
1367 if (!(source
= pa_namereg_get(c
, k
, PA_NAMEREG_SOURCE
))) {
1368 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1372 if (pa_source_output_move_to(so
, source
, TRUE
) < 0) {
1373 pa_strbuf_puts(buf
, "Moved failed.\n");
1379 static int pa_cli_command_suspend_sink(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1384 pa_core_assert_ref(c
);
1389 if (!(n
= pa_tokenizer_get(t
, 1))) {
1390 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1394 if (!(m
= pa_tokenizer_get(t
, 2))) {
1395 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1399 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1400 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1404 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
1405 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1409 if ((r
= pa_sink_suspend(sink
, suspend
, PA_SUSPEND_USER
)) < 0)
1410 pa_strbuf_printf(buf
, "Failed to resume/suspend sink: %s\n", pa_strerror(r
));
1415 static int pa_cli_command_suspend_source(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1420 pa_core_assert_ref(c
);
1425 if (!(n
= pa_tokenizer_get(t
, 1))) {
1426 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1430 if (!(m
= pa_tokenizer_get(t
, 2))) {
1431 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1435 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1436 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1440 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
1441 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1445 if ((r
= pa_source_suspend(source
, suspend
, PA_SUSPEND_USER
)) < 0)
1446 pa_strbuf_printf(buf
, "Failed to resume/suspend source: %s\n", pa_strerror(r
));
1451 static int pa_cli_command_suspend(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1455 pa_core_assert_ref(c
);
1460 if (!(m
= pa_tokenizer_get(t
, 1))) {
1461 pa_strbuf_puts(buf
, "You need to specify a suspend switch setting (0/1).\n");
1465 if ((suspend
= pa_parse_boolean(m
)) < 0) {
1466 pa_strbuf_puts(buf
, "Failed to parse suspend switch.\n");
1470 if ((r
= pa_sink_suspend_all(c
, suspend
, PA_SUSPEND_USER
)) < 0)
1471 pa_strbuf_printf(buf
, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r
));
1473 if ((r
= pa_source_suspend_all(c
, suspend
, PA_SUSPEND_USER
)) < 0)
1474 pa_strbuf_printf(buf
, "Failed to resume/suspend all sources: %s\n", pa_strerror(r
));
1479 static int pa_cli_command_log_target(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1482 pa_core_assert_ref(c
);
1487 if (!(m
= pa_tokenizer_get(t
, 1))) {
1488 pa_strbuf_puts(buf
, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
1492 if (pa_streq(m
, "null"))
1493 pa_log_set_target(PA_LOG_NULL
);
1494 else if (pa_streq(m
, "syslog"))
1495 pa_log_set_target(PA_LOG_SYSLOG
);
1496 else if (pa_streq(m
, "stderr") || pa_streq(m
, "auto")) {
1497 /* 'auto' is actually the effect with 'stderr' */
1498 pa_log_set_target(PA_LOG_STDERR
);
1499 } else if (pa_startswith(m
, "file:")) {
1500 const char *file_path
= m
+ 5;
1503 /* Open target file with user rights */
1504 if ((log_fd
= open(file_path
, O_RDWR
|O_TRUNC
|O_CREAT
, S_IRUSR
| S_IWUSR
)) >= 0) {
1505 pa_log_set_target(PA_LOG_FD
);
1506 pa_log_set_fd(log_fd
);
1508 pa_strbuf_printf(buf
, "Failed to open target file %s, error : %s\n", file_path
, pa_cstrerror(errno
));
1512 pa_strbuf_puts(buf
, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
1519 static int pa_cli_command_log_level(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1523 pa_core_assert_ref(c
);
1528 if (!(m
= pa_tokenizer_get(t
, 1))) {
1529 pa_strbuf_puts(buf
, "You need to specify a log level (0..4).\n");
1533 if (pa_atou(m
, &level
) < 0 || level
>= PA_LOG_LEVEL_MAX
) {
1534 pa_strbuf_puts(buf
, "Failed to parse log level.\n");
1538 pa_log_set_level(level
);
1543 static int pa_cli_command_log_meta(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1547 pa_core_assert_ref(c
);
1552 if (!(m
= pa_tokenizer_get(t
, 1))) {
1553 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1557 if ((b
= pa_parse_boolean(m
)) < 0) {
1558 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1562 pa_log_set_flags(PA_LOG_PRINT_META
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1567 static int pa_cli_command_log_time(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1571 pa_core_assert_ref(c
);
1576 if (!(m
= pa_tokenizer_get(t
, 1))) {
1577 pa_strbuf_puts(buf
, "You need to specify a boolean.\n");
1581 if ((b
= pa_parse_boolean(m
)) < 0) {
1582 pa_strbuf_puts(buf
, "Failed to parse log meta switch.\n");
1586 pa_log_set_flags(PA_LOG_PRINT_TIME
, b
? PA_LOG_SET
: PA_LOG_UNSET
);
1591 static int pa_cli_command_log_backtrace(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1595 pa_core_assert_ref(c
);
1600 if (!(m
= pa_tokenizer_get(t
, 1))) {
1601 pa_strbuf_puts(buf
, "You need to specify a backtrace level.\n");
1605 if (pa_atou(m
, &nframes
) < 0 || nframes
>= 1000) {
1606 pa_strbuf_puts(buf
, "Failed to parse backtrace level.\n");
1610 pa_log_set_show_backtrace(nframes
);
1615 static int pa_cli_command_card_profile(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1619 pa_core_assert_ref(c
);
1624 if (!(n
= pa_tokenizer_get(t
, 1))) {
1625 pa_strbuf_puts(buf
, "You need to specify a card either by its name or its index.\n");
1629 if (!(p
= pa_tokenizer_get(t
, 2))) {
1630 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1634 if (!(card
= pa_namereg_get(c
, n
, PA_NAMEREG_CARD
))) {
1635 pa_strbuf_puts(buf
, "No card found by this name or index.\n");
1639 if (pa_card_set_profile(card
, p
, TRUE
) < 0) {
1640 pa_strbuf_printf(buf
, "Failed to set card profile to '%s'.\n", p
);
1647 static int pa_cli_command_sink_port(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1651 pa_core_assert_ref(c
);
1656 if (!(n
= pa_tokenizer_get(t
, 1))) {
1657 pa_strbuf_puts(buf
, "You need to specify a sink either by its name or its index.\n");
1661 if (!(p
= pa_tokenizer_get(t
, 2))) {
1662 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1666 if (!(sink
= pa_namereg_get(c
, n
, PA_NAMEREG_SINK
))) {
1667 pa_strbuf_puts(buf
, "No sink found by this name or index.\n");
1671 if (pa_sink_set_port(sink
, p
, TRUE
) < 0) {
1672 pa_strbuf_printf(buf
, "Failed to set sink port to '%s'.\n", p
);
1679 static int pa_cli_command_source_port(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1683 pa_core_assert_ref(c
);
1688 if (!(n
= pa_tokenizer_get(t
, 1))) {
1689 pa_strbuf_puts(buf
, "You need to specify a source either by its name or its index.\n");
1693 if (!(p
= pa_tokenizer_get(t
, 2))) {
1694 pa_strbuf_puts(buf
, "You need to specify a profile by its name.\n");
1698 if (!(source
= pa_namereg_get(c
, n
, PA_NAMEREG_SOURCE
))) {
1699 pa_strbuf_puts(buf
, "No source found by this name or index.\n");
1703 if (pa_source_set_port(source
, p
, TRUE
) < 0) {
1704 pa_strbuf_printf(buf
, "Failed to set source port to '%s'.\n", p
);
1711 static int pa_cli_command_dump(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1723 pa_core_assert_ref(c
);
1731 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime_r(&now
, txt
));
1733 pa_strbuf_printf(buf
, "### Configuration dump generated at %s\n", ctime(&now
));
1736 PA_IDXSET_FOREACH(m
, c
->modules
, idx
) {
1738 pa_strbuf_printf(buf
, "load-module %s", m
->name
);
1741 pa_strbuf_printf(buf
, " %s", m
->argument
);
1743 pa_strbuf_puts(buf
, "\n");
1747 PA_IDXSET_FOREACH(sink
, c
->sinks
, idx
) {
1750 pa_strbuf_puts(buf
, "\n");
1754 pa_strbuf_printf(buf
, "set-sink-volume %s 0x%03x\n", sink
->name
, pa_cvolume_max(pa_sink_get_volume(sink
, FALSE
)));
1755 pa_strbuf_printf(buf
, "set-sink-mute %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_mute(sink
, FALSE
)));
1756 pa_strbuf_printf(buf
, "suspend-sink %s %s\n", sink
->name
, pa_yes_no(pa_sink_get_state(sink
) == PA_SINK_SUSPENDED
));
1760 PA_IDXSET_FOREACH(source
, c
->sources
, idx
) {
1763 pa_strbuf_puts(buf
, "\n");
1767 pa_strbuf_printf(buf
, "set-source-volume %s 0x%03x\n", source
->name
, pa_cvolume_max(pa_source_get_volume(source
, FALSE
)));
1768 pa_strbuf_printf(buf
, "set-source-mute %s %s\n", source
->name
, pa_yes_no(pa_source_get_mute(source
, FALSE
)));
1769 pa_strbuf_printf(buf
, "suspend-source %s %s\n", source
->name
, pa_yes_no(pa_source_get_state(source
) == PA_SOURCE_SUSPENDED
));
1773 PA_IDXSET_FOREACH(card
, c
->cards
, idx
) {
1776 pa_strbuf_puts(buf
, "\n");
1780 if (card
->active_profile
)
1781 pa_strbuf_printf(buf
, "set-card-profile %s %s\n", card
->name
, card
->active_profile
->name
);
1785 if ((sink
= pa_namereg_get_default_sink(c
))) {
1787 pa_strbuf_puts(buf
, "\n");
1791 pa_strbuf_printf(buf
, "set-default-sink %s\n", sink
->name
);
1794 if ((source
= pa_namereg_get_default_source(c
))) {
1796 pa_strbuf_puts(buf
, "\n");
1798 pa_strbuf_printf(buf
, "set-default-source %s\n", source
->name
);
1801 pa_strbuf_puts(buf
, "\n### EOF\n");
1806 static int pa_cli_command_dump_volumes(pa_core
*c
, pa_tokenizer
*t
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
1810 pa_source_output
*o
;
1811 uint32_t s_idx
, i_idx
;
1812 char v_str
[PA_CVOLUME_SNPRINT_MAX
];
1814 pa_core_assert_ref(c
);
1819 PA_IDXSET_FOREACH(s
, c
->sinks
, s_idx
) {
1820 pa_strbuf_printf(buf
, "Sink %d: ", s_idx
);
1821 pa_strbuf_printf(buf
, "reference = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &s
->reference_volume
));
1822 pa_strbuf_printf(buf
, "real = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &s
->real_volume
));
1823 pa_strbuf_printf(buf
, "soft = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &s
->soft_volume
));
1824 pa_strbuf_printf(buf
, "current_hw = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &s
->thread_info
.current_hw_volume
));
1825 pa_strbuf_printf(buf
, "save = %s\n", pa_yes_no(s
->save_volume
));
1827 PA_IDXSET_FOREACH(i
, s
->inputs
, i_idx
) {
1828 pa_strbuf_printf(buf
, "\tInput %d: ", i_idx
);
1829 pa_strbuf_printf(buf
, "volume = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->volume
));
1830 pa_strbuf_printf(buf
, "reference_ratio = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->reference_ratio
));
1831 pa_strbuf_printf(buf
, "real_ratio = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->real_ratio
));
1832 pa_strbuf_printf(buf
, "soft = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->soft_volume
));
1833 pa_strbuf_printf(buf
, "volume_factor = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->volume_factor
));
1834 pa_strbuf_printf(buf
, "volume_factor_sink = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &i
->volume_factor_sink
));
1835 pa_strbuf_printf(buf
, "save = %s\n", pa_yes_no(i
->save_volume
));
1839 PA_IDXSET_FOREACH(so
, c
->sources
, s_idx
) {
1840 pa_strbuf_printf(buf
, "Source %d: ", s_idx
);
1841 pa_strbuf_printf(buf
, "reference = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &so
->reference_volume
));
1842 pa_strbuf_printf(buf
, "real = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &so
->real_volume
));
1843 pa_strbuf_printf(buf
, "soft = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &so
->soft_volume
));
1844 pa_strbuf_printf(buf
, "current_hw = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &so
->thread_info
.current_hw_volume
));
1845 pa_strbuf_printf(buf
, "save = %s\n", pa_yes_no(so
->save_volume
));
1847 PA_IDXSET_FOREACH(o
, so
->outputs
, i_idx
) {
1848 pa_strbuf_printf(buf
, "\tOutput %d: ", i_idx
);
1849 pa_strbuf_printf(buf
, "volume = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->volume
));
1850 pa_strbuf_printf(buf
, "reference_ratio = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->reference_ratio
));
1851 pa_strbuf_printf(buf
, "real_ratio = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->real_ratio
));
1852 pa_strbuf_printf(buf
, "soft = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->soft_volume
));
1853 pa_strbuf_printf(buf
, "volume_factor = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->volume_factor
));
1854 pa_strbuf_printf(buf
, "volume_factor_source = %s, ", pa_cvolume_snprint(v_str
, sizeof(v_str
), &o
->volume_factor_source
));
1855 pa_strbuf_printf(buf
, "save = %s\n", pa_yes_no(o
->save_volume
));
1862 int pa_cli_command_execute_line_stateful(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
, int *ifstate
) {
1869 cs
= s
+strspn(s
, whitespace
);
1871 if (*cs
== '#' || !*cs
)
1873 else if (*cs
== '.') {
1874 if (!strcmp(cs
, META_ELSE
)) {
1875 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1876 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1878 } else if (*ifstate
== IFSTATE_TRUE
)
1879 *ifstate
= IFSTATE_FALSE
;
1881 *ifstate
= IFSTATE_TRUE
;
1883 } else if (!strcmp(cs
, META_ENDIF
)) {
1884 if (!ifstate
|| *ifstate
== IFSTATE_NONE
) {
1885 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1888 *ifstate
= IFSTATE_NONE
;
1891 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
1893 if (!strcmp(cs
, META_FAIL
))
1895 else if (!strcmp(cs
, META_NOFAIL
))
1899 l
= strcspn(cs
, whitespace
);
1901 if (l
== sizeof(META_INCLUDE
)-1 && !strncmp(cs
, META_INCLUDE
, l
)) {
1903 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1905 if (stat(filename
, &st
) < 0) {
1906 pa_log_warn("stat('%s'): %s", filename
, pa_cstrerror(errno
));
1910 if (S_ISDIR(st
.st_mode
)) {
1913 if (!(d
= opendir(filename
))) {
1914 pa_log_warn("Failed to read '%s': %s", filename
, pa_cstrerror(errno
));
1919 char **sorted_files
;
1921 pa_bool_t failed
= FALSE
;
1922 pa_dynarray
*files
= pa_dynarray_new();
1924 while ((de
= readdir(d
))) {
1926 size_t flen
= strlen(de
->d_name
);
1931 extn
= &de
->d_name
[flen
-3];
1932 if (strncmp(extn
, ".pa", 3) == 0)
1933 pa_dynarray_append(files
, pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", filename
, de
->d_name
));
1938 count
= pa_dynarray_size(files
);
1939 sorted_files
= pa_xnew(char*, count
);
1940 for (i
= 0; i
< count
; ++i
)
1941 sorted_files
[i
] = pa_dynarray_get(files
, i
);
1942 pa_dynarray_free(files
, NULL
);
1944 for (i
= 0; i
< count
; ++i
) {
1945 for (unsigned j
= 0; j
< count
; ++j
) {
1946 if (strcmp(sorted_files
[i
], sorted_files
[j
]) < 0) {
1947 char *tmp
= sorted_files
[i
];
1948 sorted_files
[i
] = sorted_files
[j
];
1949 sorted_files
[j
] = tmp
;
1954 for (i
= 0; i
< count
; ++i
) {
1956 if (pa_cli_command_execute_file(c
, sorted_files
[i
], buf
, fail
) < 0 && *fail
)
1960 pa_xfree(sorted_files
[i
]);
1962 pa_xfree(sorted_files
);
1966 } else if (pa_cli_command_execute_file(c
, filename
, buf
, fail
) < 0 && *fail
) {
1970 } else if (l
== sizeof(META_IFEXISTS
)-1 && !strncmp(cs
, META_IFEXISTS
, l
)) {
1972 pa_strbuf_printf(buf
, "Meta command %s is not valid in this context\n", cs
);
1974 } else if (*ifstate
!= IFSTATE_NONE
) {
1975 pa_strbuf_printf(buf
, "Nested %s commands not supported\n", cs
);
1978 const char *filename
= cs
+l
+strspn(cs
+l
, whitespace
);
1980 /* Search DL_SEARCH_PATH unless the filename is absolute */
1981 if (filename
[0] == PA_PATH_SEP_CHAR
) {
1983 *ifstate
= access(filename
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
1984 pa_log_debug("Checking for existence of '%s': %s", filename
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
1987 const char *paths
, *state
= NULL
;
1990 if (!(paths
= lt_dlgetsearchpath()))
1993 while ((p
= pa_split(paths
, ":", &state
))) {
1996 pathname
= pa_sprintf_malloc("%s" PA_PATH_SEP
"%s", p
, filename
);
1999 *ifstate
= access(pathname
, F_OK
) == 0 ? IFSTATE_TRUE
: IFSTATE_FALSE
;
2000 pa_log_debug("Checking for existence of '%s': %s", pathname
, *ifstate
== IFSTATE_TRUE
? "success" : "failure");
2004 if (*ifstate
== IFSTATE_TRUE
)
2011 pa_strbuf_printf(buf
, "Invalid meta command: %s\n", cs
);
2012 if (*fail
) return -1;
2016 const struct command
*command
;
2020 if (ifstate
&& *ifstate
== IFSTATE_FALSE
)
2023 l
= strcspn(cs
, whitespace
);
2025 for (command
= commands
; command
->name
; command
++)
2026 if (strlen(command
->name
) == l
&& !strncmp(cs
, command
->name
, l
)) {
2028 pa_tokenizer
*t
= pa_tokenizer_new(cs
, command
->args
);
2030 ret
= command
->proc(c
, t
, buf
, fail
);
2031 pa_tokenizer_free(t
);
2034 if (ret
< 0 && *fail
)
2041 pa_strbuf_printf(buf
, "Unknown command: %s\n", cs
);
2050 int pa_cli_command_execute_line(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
2051 return pa_cli_command_execute_line_stateful(c
, s
, buf
, fail
, NULL
);
2054 int pa_cli_command_execute_file_stream(pa_core
*c
, FILE *f
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
2056 int ifstate
= IFSTATE_NONE
;
2058 pa_bool_t _fail
= TRUE
;
2067 while (fgets(line
, sizeof(line
), f
)) {
2070 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
)
2081 int pa_cli_command_execute_file(pa_core
*c
, const char *fn
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
2084 pa_bool_t _fail
= TRUE
;
2093 if (!(f
= pa_fopen_cloexec(fn
, "r"))) {
2094 pa_strbuf_printf(buf
, "open('%s') failed: %s\n", fn
, pa_cstrerror(errno
));
2100 pa_log_debug("Parsing script '%s'", fn
);
2101 ret
= pa_cli_command_execute_file_stream(c
, f
, buf
, fail
);
2110 int pa_cli_command_execute(pa_core
*c
, const char *s
, pa_strbuf
*buf
, pa_bool_t
*fail
) {
2112 int ifstate
= IFSTATE_NONE
;
2113 pa_bool_t _fail
= TRUE
;
2124 size_t l
= strcspn(p
, linebreak
);
2125 char *line
= pa_xstrndup(p
, l
);
2127 if (pa_cli_command_execute_line_stateful(c
, line
, buf
, fail
, &ifstate
) < 0 && *fail
) {
2134 p
+= strspn(p
, linebreak
);