LCOV - code coverage report
Current view: top level - pulsecore - cli-command.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 0 1101 0.0 %
Date: 2012-07-17 Functions: 0 61 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 896 0.0 %

           Branch data     Line data    Source code
       1                 :            : /***
       2                 :            :   This file is part of PulseAudio.
       3                 :            : 
       4                 :            :   Copyright 2004-2006 Lennart Poettering
       5                 :            :   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
       6                 :            : 
       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.
      11                 :            : 
      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.
      16                 :            : 
      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
      20                 :            :   USA.
      21                 :            : ***/
      22                 :            : 
      23                 :            : #ifdef HAVE_CONFIG_H
      24                 :            : #include <config.h>
      25                 :            : #endif
      26                 :            : 
      27                 :            : #include <stdio.h>
      28                 :            : #include <string.h>
      29                 :            : #include <stdlib.h>
      30                 :            : #include <errno.h>
      31                 :            : #include <unistd.h>
      32                 :            : #include <ltdl.h>
      33                 :            : #include <sys/stat.h>
      34                 :            : #include <dirent.h>
      35                 :            : #include <time.h>
      36                 :            : #include <fcntl.h>
      37                 :            : #include <ctype.h>
      38                 :            : 
      39                 :            : #include <pulse/xmalloc.h>
      40                 :            : #include <pulse/error.h>
      41                 :            : 
      42                 :            : #include <pulsecore/module.h>
      43                 :            : #include <pulsecore/sink.h>
      44                 :            : #include <pulsecore/source.h>
      45                 :            : #include <pulsecore/client.h>
      46                 :            : #include <pulsecore/sink-input.h>
      47                 :            : #include <pulsecore/source-output.h>
      48                 :            : #include <pulsecore/tokenizer.h>
      49                 :            : #include <pulsecore/strbuf.h>
      50                 :            : #include <pulsecore/namereg.h>
      51                 :            : #include <pulsecore/cli-text.h>
      52                 :            : #include <pulsecore/core-scache.h>
      53                 :            : #include <pulsecore/sound-file.h>
      54                 :            : #include <pulsecore/play-memchunk.h>
      55                 :            : #include <pulsecore/sound-file-stream.h>
      56                 :            : #include <pulsecore/shared.h>
      57                 :            : #include <pulsecore/core-util.h>
      58                 :            : #include <pulsecore/core-error.h>
      59                 :            : #include <pulsecore/modinfo.h>
      60                 :            : #include <pulsecore/dynarray.h>
      61                 :            : 
      62                 :            : #include "cli-command.h"
      63                 :            : 
      64                 :            : struct command {
      65                 :            :     const char *name;
      66                 :            :     int (*proc) (pa_core *c, pa_tokenizer*t, pa_strbuf *buf, pa_bool_t *fail);
      67                 :            :     const char *help;
      68                 :            :     unsigned args;
      69                 :            : };
      70                 :            : 
      71                 :            : #define META_INCLUDE ".include"
      72                 :            : #define META_FAIL ".fail"
      73                 :            : #define META_NOFAIL ".nofail"
      74                 :            : #define META_IFEXISTS ".ifexists"
      75                 :            : #define META_ELSE ".else"
      76                 :            : #define META_ENDIF ".endif"
      77                 :            : 
      78                 :            : enum {
      79                 :            :     IFSTATE_NONE = -1,
      80                 :            :     IFSTATE_FALSE = 0,
      81                 :            :     IFSTATE_TRUE = 1,
      82                 :            : };
      83                 :            : 
      84                 :            : /* Prototypes for all available commands */
      85                 :            : static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      86                 :            : static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      87                 :            : static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      88                 :            : static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      89                 :            : static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      90                 :            : static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      91                 :            : static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      92                 :            : static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      93                 :            : static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      94                 :            : static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      95                 :            : static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      96                 :            : static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      97                 :            : static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      98                 :            : static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
      99                 :            : static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     100                 :            : static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     101                 :            : static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     102                 :            : static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     103                 :            : static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     104                 :            : static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     105                 :            : static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     106                 :            : static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     107                 :            : static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     108                 :            : static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     109                 :            : static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     110                 :            : static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     111                 :            : static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     112                 :            : static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     113                 :            : static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     114                 :            : static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     115                 :            : static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     116                 :            : static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     117                 :            : static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     118                 :            : static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     119                 :            : static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     120                 :            : static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     121                 :            : static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     122                 :            : static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     123                 :            : static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     124                 :            : static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     125                 :            : static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     126                 :            : static int pa_cli_command_log_target(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     127                 :            : static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     128                 :            : static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     129                 :            : static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     130                 :            : static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     131                 :            : static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     132                 :            : static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     133                 :            : static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     134                 :            : static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     135                 :            : static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     136                 :            : static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     137                 :            : static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     138                 :            : static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     139                 :            : static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
     140                 :            : 
     141                 :            : /* A method table for all available commands */
     142                 :            : 
     143                 :            : static const struct command commands[] = {
     144                 :            :     { "help",                    pa_cli_command_help,               "Show this help",               1 },
     145                 :            :     { "list-modules",            pa_cli_command_modules,            "List loaded modules",          1 },
     146                 :            :     { "list-cards",              pa_cli_command_cards,              "List cards",                   1 },
     147                 :            :     { "list-sinks",              pa_cli_command_sinks,              "List loaded sinks",            1 },
     148                 :            :     { "list-sources",            pa_cli_command_sources,            "List loaded sources",          1 },
     149                 :            :     { "list-clients",            pa_cli_command_clients,            "List loaded clients",          1 },
     150                 :            :     { "list-sink-inputs",        pa_cli_command_sink_inputs,        "List sink inputs",             1 },
     151                 :            :     { "list-source-outputs",     pa_cli_command_source_outputs,     "List source outputs",          1 },
     152                 :            :     { "stat",                    pa_cli_command_stat,               "Show memory block statistics", 1 },
     153                 :            :     { "info",                    pa_cli_command_info,               "Show comprehensive status",    1 },
     154                 :            :     { "ls",                      pa_cli_command_info,               NULL,                           1 },
     155                 :            :     { "list",                    pa_cli_command_info,               NULL,                           1 },
     156                 :            :     { "load-module",             pa_cli_command_load,               "Load a module (args: name, arguments)", 3},
     157                 :            :     { "unload-module",           pa_cli_command_unload,             "Unload a module (args: index|name)", 2},
     158                 :            :     { "describe-module",         pa_cli_command_describe,           "Describe a module (arg: name)", 2},
     159                 :            :     { "set-sink-volume",         pa_cli_command_sink_volume,        "Set the volume of a sink (args: index|name, volume)", 3},
     160                 :            :     { "set-source-volume",       pa_cli_command_source_volume,      "Set the volume of a source (args: index|name, volume)", 3},
     161                 :            :     { "set-sink-mute",           pa_cli_command_sink_mute,          "Set the mute switch of a sink (args: index|name, bool)", 3},
     162                 :            :     { "set-source-mute",         pa_cli_command_source_mute,        "Set the mute switch of a source (args: index|name, bool)", 3},
     163                 :            :     { "set-sink-input-volume",   pa_cli_command_sink_input_volume,  "Set the volume of a sink input (args: index, volume)", 3},
     164                 :            :     { "set-source-output-volume",pa_cli_command_source_output_volume,"Set the volume of a source output (args: index, volume)", 3},
     165                 :            :     { "set-sink-input-mute",     pa_cli_command_sink_input_mute,    "Set the mute switch of a sink input (args: index, bool)", 3},
     166                 :            :     { "set-source-output-mute",  pa_cli_command_source_output_mute, "Set the mute switch of a source output (args: index, bool)", 3},
     167                 :            :     { "set-default-sink",        pa_cli_command_sink_default,       "Set the default sink (args: index|name)", 2},
     168                 :            :     { "set-default-source",      pa_cli_command_source_default,     "Set the default source (args: index|name)", 2},
     169                 :            :     { "set-card-profile",        pa_cli_command_card_profile,       "Change the profile of a card (args: index|name, profile-name)", 3},
     170                 :            :     { "set-sink-port",           pa_cli_command_sink_port,          "Change the port of a sink (args: index|name, port-name)", 3},
     171                 :            :     { "set-source-port",         pa_cli_command_source_port,        "Change the port of a source (args: index|name, port-name)", 3},
     172                 :            :     { "set-port-latency-offset", pa_cli_command_port_offset,        "Change the latency of a port (args: card-index|card-name, port-name, latency-offset)", 4},
     173                 :            :     { "suspend-sink",            pa_cli_command_suspend_sink,       "Suspend sink (args: index|name, bool)", 3},
     174                 :            :     { "suspend-source",          pa_cli_command_suspend_source,     "Suspend source (args: index|name, bool)", 3},
     175                 :            :     { "suspend",                 pa_cli_command_suspend,            "Suspend all sinks and all sources (args: bool)", 2},
     176                 :            :     { "move-sink-input",         pa_cli_command_move_sink_input,    "Move sink input to another sink (args: index, sink)", 3},
     177                 :            :     { "move-source-output",      pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3},
     178                 :            :     { "update-sink-proplist",    pa_cli_command_update_sink_proplist, "Update the properties of a sink (args: index|name, properties)", 3},
     179                 :            :     { "update-source-proplist",  pa_cli_command_update_source_proplist, "Update the properties of a source (args: index|name, properties)", 3},
     180                 :            :     { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist, "Update the properties of a sink input (args: index, properties)", 3},
     181                 :            :     { "update-source-output-proplist", pa_cli_command_update_source_output_proplist, "Update the properties of a source output (args: index, properties)", 3},
     182                 :            :     { "list-samples",            pa_cli_command_scache_list,        "List all entries in the sample cache", 1},
     183                 :            :     { "play-sample",             pa_cli_command_scache_play,        "Play a sample from the sample cache (args: name, sink|index)", 3},
     184                 :            :     { "remove-sample",           pa_cli_command_scache_remove,      "Remove a sample from the sample cache (args: name)", 2},
     185                 :            :     { "load-sample",             pa_cli_command_scache_load,        "Load a sound file into the sample cache (args: name, filename)", 3},
     186                 :            :     { "load-sample-lazy",        pa_cli_command_scache_load,        "Lazily load a sound file into the sample cache (args: name, filename)", 3},
     187                 :            :     { "load-sample-dir-lazy",    pa_cli_command_scache_load_dir,    "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
     188                 :            :     { "kill-client",             pa_cli_command_kill_client,        "Kill a client (args: index)", 2},
     189                 :            :     { "kill-sink-input",         pa_cli_command_kill_sink_input,    "Kill a sink input (args: index)", 2},
     190                 :            :     { "kill-source-output",      pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2},
     191                 :            :     { "set-log-target",          pa_cli_command_log_target,         "Change the log target (args: null,auto,syslog,stderr,file:PATH)", 2},
     192                 :            :     { "set-log-level",           pa_cli_command_log_level,          "Change the log level (args: numeric level)", 2},
     193                 :            :     { "set-log-meta",            pa_cli_command_log_meta,           "Show source code location in log messages (args: bool)", 2},
     194                 :            :     { "set-log-time",            pa_cli_command_log_time,           "Show timestamps in log messages (args: bool)", 2},
     195                 :            :     { "set-log-backtrace",       pa_cli_command_log_backtrace,      "Show backtrace in log messages (args: frames)", 2},
     196                 :            :     { "play-file",               pa_cli_command_play_file,          "Play a sound file (args: filename, sink|index)", 3},
     197                 :            :     { "dump",                    pa_cli_command_dump,               "Dump daemon configuration", 1},
     198                 :            :     { "dump-volumes",            pa_cli_command_dump_volumes,       "Debug: Show the state of all volumes", 1 },
     199                 :            :     { "shared",                  pa_cli_command_list_shared_props,  "Debug: Show shared properties", 1},
     200                 :            :     { "exit",                    pa_cli_command_exit,               "Terminate the daemon",         1 },
     201                 :            :     { "vacuum",                  pa_cli_command_vacuum,             NULL, 1},
     202                 :            :     { NULL, NULL, NULL, 0 }
     203                 :            : };
     204                 :            : 
     205                 :            : static const char whitespace[] = " \t\n\r";
     206                 :            : static const char linebreak[] = "\n\r";
     207                 :            : 
     208                 :          0 : static uint32_t parse_index(const char *n) {
     209                 :            :     uint32_t idx;
     210                 :            : 
     211         [ #  # ]:          0 :     if (pa_atou(n, &idx) < 0)
     212                 :            :         return (uint32_t) PA_IDXSET_INVALID;
     213                 :            : 
     214                 :          0 :     return idx;
     215                 :            : }
     216                 :            : 
     217                 :          0 : static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     218                 :          0 :     pa_core_assert_ref(c);
     219         [ #  # ]:          0 :     pa_assert(t);
     220         [ #  # ]:          0 :     pa_assert(buf);
     221         [ #  # ]:          0 :     pa_assert(fail);
     222                 :            : 
     223         [ #  # ]:          0 :     if (pa_core_exit(c, FALSE, 0) < 0)
     224                 :          0 :         pa_strbuf_puts(buf, "Not allowed to terminate daemon.\n");
     225                 :            : 
     226                 :          0 :     return 0;
     227                 :            : }
     228                 :            : 
     229                 :          0 : static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     230                 :            :     const struct command*command;
     231                 :            : 
     232                 :          0 :     pa_core_assert_ref(c);
     233         [ #  # ]:          0 :     pa_assert(t);
     234         [ #  # ]:          0 :     pa_assert(buf);
     235         [ #  # ]:          0 :     pa_assert(fail);
     236                 :            : 
     237                 :          0 :     pa_strbuf_puts(buf, "Available commands:\n");
     238                 :            : 
     239         [ #  # ]:          0 :     for (command = commands; command->name; command++)
     240         [ #  # ]:          0 :         if (command->help)
     241                 :          0 :             pa_strbuf_printf(buf, "    %-25s %s\n", command->name, command->help);
     242                 :          0 :     return 0;
     243                 :            : }
     244                 :            : 
     245                 :          0 : static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     246                 :            :     char *s;
     247                 :            : 
     248                 :          0 :     pa_core_assert_ref(c);
     249         [ #  # ]:          0 :     pa_assert(t);
     250         [ #  # ]:          0 :     pa_assert(buf);
     251         [ #  # ]:          0 :     pa_assert(fail);
     252                 :            : 
     253         [ #  # ]:          0 :     pa_assert_se(s = pa_module_list_to_string(c));
     254                 :          0 :     pa_strbuf_puts(buf, s);
     255                 :          0 :     pa_xfree(s);
     256                 :          0 :     return 0;
     257                 :            : }
     258                 :            : 
     259                 :          0 : static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     260                 :            :     char *s;
     261                 :            : 
     262                 :          0 :     pa_core_assert_ref(c);
     263         [ #  # ]:          0 :     pa_assert(t);
     264         [ #  # ]:          0 :     pa_assert(buf);
     265         [ #  # ]:          0 :     pa_assert(fail);
     266                 :            : 
     267         [ #  # ]:          0 :     pa_assert_se(s = pa_client_list_to_string(c));
     268                 :          0 :     pa_strbuf_puts(buf, s);
     269                 :          0 :     pa_xfree(s);
     270                 :          0 :     return 0;
     271                 :            : }
     272                 :            : 
     273                 :          0 : static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     274                 :            :     char *s;
     275                 :            : 
     276                 :          0 :     pa_core_assert_ref(c);
     277         [ #  # ]:          0 :     pa_assert(t);
     278         [ #  # ]:          0 :     pa_assert(buf);
     279         [ #  # ]:          0 :     pa_assert(fail);
     280                 :            : 
     281         [ #  # ]:          0 :     pa_assert_se(s = pa_card_list_to_string(c));
     282                 :          0 :     pa_strbuf_puts(buf, s);
     283                 :          0 :     pa_xfree(s);
     284                 :          0 :     return 0;
     285                 :            : }
     286                 :            : 
     287                 :          0 : static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     288                 :            :     char *s;
     289                 :            : 
     290                 :          0 :     pa_core_assert_ref(c);
     291         [ #  # ]:          0 :     pa_assert(t);
     292         [ #  # ]:          0 :     pa_assert(buf);
     293         [ #  # ]:          0 :     pa_assert(fail);
     294                 :            : 
     295         [ #  # ]:          0 :     pa_assert_se(s = pa_sink_list_to_string(c));
     296                 :          0 :     pa_strbuf_puts(buf, s);
     297                 :          0 :     pa_xfree(s);
     298                 :          0 :     return 0;
     299                 :            : }
     300                 :            : 
     301                 :          0 : static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     302                 :            :     char *s;
     303                 :            : 
     304                 :          0 :     pa_core_assert_ref(c);
     305         [ #  # ]:          0 :     pa_assert(t);
     306         [ #  # ]:          0 :     pa_assert(buf);
     307         [ #  # ]:          0 :     pa_assert(fail);
     308                 :            : 
     309         [ #  # ]:          0 :     pa_assert_se(s = pa_source_list_to_string(c));
     310                 :          0 :     pa_strbuf_puts(buf, s);
     311                 :          0 :     pa_xfree(s);
     312                 :          0 :     return 0;
     313                 :            : }
     314                 :            : 
     315                 :          0 : static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     316                 :            :     char *s;
     317                 :            : 
     318                 :          0 :     pa_core_assert_ref(c);
     319         [ #  # ]:          0 :     pa_assert(t);
     320         [ #  # ]:          0 :     pa_assert(buf);
     321         [ #  # ]:          0 :     pa_assert(fail);
     322                 :            : 
     323         [ #  # ]:          0 :     pa_assert_se(s = pa_sink_input_list_to_string(c));
     324                 :          0 :     pa_strbuf_puts(buf, s);
     325                 :          0 :     pa_xfree(s);
     326                 :          0 :     return 0;
     327                 :            : }
     328                 :            : 
     329                 :          0 : static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     330                 :            :     char *s;
     331                 :            : 
     332                 :          0 :     pa_core_assert_ref(c);
     333         [ #  # ]:          0 :     pa_assert(t);
     334         [ #  # ]:          0 :     pa_assert(buf);
     335         [ #  # ]:          0 :     pa_assert(fail);
     336                 :            : 
     337         [ #  # ]:          0 :     pa_assert_se(s = pa_source_output_list_to_string(c));
     338                 :          0 :     pa_strbuf_puts(buf, s);
     339                 :          0 :     pa_xfree(s);
     340                 :          0 :     return 0;
     341                 :            : }
     342                 :            : 
     343                 :          0 : static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     344                 :            :     char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
     345                 :            :     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
     346                 :            :     char bytes[PA_BYTES_SNPRINT_MAX];
     347                 :            :     const pa_mempool_stat *mstat;
     348                 :            :     unsigned k;
     349                 :            :     pa_sink *def_sink;
     350                 :            :     pa_source *def_source;
     351                 :            : 
     352                 :            :     static const char* const type_table[PA_MEMBLOCK_TYPE_MAX] = {
     353                 :            :         [PA_MEMBLOCK_POOL] = "POOL",
     354                 :            :         [PA_MEMBLOCK_POOL_EXTERNAL] = "POOL_EXTERNAL",
     355                 :            :         [PA_MEMBLOCK_APPENDED] = "APPENDED",
     356                 :            :         [PA_MEMBLOCK_USER] = "USER",
     357                 :            :         [PA_MEMBLOCK_FIXED] = "FIXED",
     358                 :            :         [PA_MEMBLOCK_IMPORTED] = "IMPORTED",
     359                 :            :     };
     360                 :            : 
     361                 :          0 :     pa_core_assert_ref(c);
     362         [ #  # ]:          0 :     pa_assert(t);
     363         [ #  # ]:          0 :     pa_assert(buf);
     364         [ #  # ]:          0 :     pa_assert(fail);
     365                 :            : 
     366                 :          0 :     mstat = pa_mempool_get_stat(c->mempool);
     367                 :            : 
     368                 :          0 :     pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
     369                 :          0 :                      (unsigned) pa_atomic_load(&mstat->n_allocated),
     370                 :          0 :                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->allocated_size)));
     371                 :            : 
     372                 :          0 :     pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
     373                 :          0 :                      (unsigned) pa_atomic_load(&mstat->n_accumulated),
     374                 :          0 :                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->accumulated_size)));
     375                 :            : 
     376                 :          0 :     pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
     377                 :          0 :                      (unsigned) pa_atomic_load(&mstat->n_imported),
     378                 :          0 :                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->imported_size)));
     379                 :            : 
     380                 :          0 :     pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
     381                 :          0 :                      (unsigned) pa_atomic_load(&mstat->n_exported),
     382                 :          0 :                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->exported_size)));
     383                 :            : 
     384                 :          0 :     pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
     385                 :          0 :                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c)));
     386                 :            : 
     387                 :          0 :     pa_strbuf_printf(buf, "Default sample spec: %s\n",
     388                 :          0 :                      pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec));
     389                 :            : 
     390                 :          0 :     pa_strbuf_printf(buf, "Default channel map: %s\n",
     391                 :          0 :                      pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
     392                 :            : 
     393                 :          0 :     def_sink = pa_namereg_get_default_sink(c);
     394                 :          0 :     def_source = pa_namereg_get_default_source(c);
     395 [ #  # ][ #  # ]:          0 :     pa_strbuf_printf(buf, "Default sink name: %s\n"
     396                 :            :                      "Default source name: %s\n",
     397                 :            :                      def_sink ? def_sink->name : "none",
     398                 :            :                      def_source ? def_source->name : "none");
     399                 :            : 
     400         [ #  # ]:          0 :     for (k = 0; k < PA_MEMBLOCK_TYPE_MAX; k++)
     401                 :          0 :         pa_strbuf_printf(buf,
     402                 :            :                          "Memory blocks of type %s: %u allocated/%u accumulated.\n",
     403                 :            :                          type_table[k],
     404                 :          0 :                          (unsigned) pa_atomic_load(&mstat->n_allocated_by_type[k]),
     405                 :          0 :                          (unsigned) pa_atomic_load(&mstat->n_accumulated_by_type[k]));
     406                 :            : 
     407                 :          0 :     return 0;
     408                 :            : }
     409                 :            : 
     410                 :          0 : static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     411                 :          0 :     pa_core_assert_ref(c);
     412         [ #  # ]:          0 :     pa_assert(t);
     413         [ #  # ]:          0 :     pa_assert(buf);
     414         [ #  # ]:          0 :     pa_assert(fail);
     415                 :            : 
     416                 :          0 :     pa_cli_command_stat(c, t, buf, fail);
     417                 :          0 :     pa_cli_command_modules(c, t, buf, fail);
     418                 :          0 :     pa_cli_command_sinks(c, t, buf, fail);
     419                 :          0 :     pa_cli_command_sources(c, t, buf, fail);
     420                 :          0 :     pa_cli_command_clients(c, t, buf, fail);
     421                 :          0 :     pa_cli_command_cards(c, t, buf, fail);
     422                 :          0 :     pa_cli_command_sink_inputs(c, t, buf, fail);
     423                 :          0 :     pa_cli_command_source_outputs(c, t, buf, fail);
     424                 :          0 :     pa_cli_command_scache_list(c, t, buf, fail);
     425                 :          0 :     return 0;
     426                 :            : }
     427                 :            : 
     428                 :          0 : static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     429                 :            :     const char *name;
     430                 :            : 
     431                 :          0 :     pa_core_assert_ref(c);
     432         [ #  # ]:          0 :     pa_assert(t);
     433         [ #  # ]:          0 :     pa_assert(buf);
     434         [ #  # ]:          0 :     pa_assert(fail);
     435                 :            : 
     436         [ #  # ]:          0 :     if (!(name = pa_tokenizer_get(t, 1))) {
     437                 :          0 :         pa_strbuf_puts(buf, "You need to specify the module name and optionally arguments.\n");
     438                 :          0 :         return -1;
     439                 :            :     }
     440                 :            : 
     441         [ #  # ]:          0 :     if (!pa_module_load(c, name,  pa_tokenizer_get(t, 2))) {
     442                 :          0 :         pa_strbuf_puts(buf, "Module load failed.\n");
     443                 :          0 :         return -1;
     444                 :            :     }
     445                 :            : 
     446                 :            :     return 0;
     447                 :            : }
     448                 :            : 
     449                 :          0 : static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     450                 :            :     pa_module *m;
     451                 :            :     uint32_t idx;
     452                 :            :     const char *i;
     453                 :          0 :     pa_bool_t unloaded = FALSE;
     454                 :            : 
     455                 :          0 :     pa_core_assert_ref(c);
     456         [ #  # ]:          0 :     pa_assert(t);
     457         [ #  # ]:          0 :     pa_assert(buf);
     458         [ #  # ]:          0 :     pa_assert(fail);
     459                 :            : 
     460         [ #  # ]:          0 :     if (!(i = pa_tokenizer_get(t, 1))) {
     461                 :          0 :         pa_strbuf_puts(buf, "You need to specify the module index or name.\n");
     462                 :          0 :         return -1;
     463                 :            :     }
     464                 :            : 
     465         [ #  # ]:          0 :     if (pa_atou(i, &idx) >= 0) {
     466         [ #  # ]:          0 :         if (!(m = pa_idxset_get_by_index(c->modules, idx))) {
     467                 :          0 :             pa_strbuf_puts(buf, "Invalid module index.\n");
     468                 :          0 :             return -1;
     469                 :            :         }
     470                 :            : 
     471                 :          0 :         pa_module_unload_request(m, FALSE);
     472                 :            : 
     473                 :            :     } else {
     474         [ #  # ]:          0 :         PA_IDXSET_FOREACH(m, c->modules, idx)
     475         [ #  # ]:          0 :             if (pa_streq(i, m->name)) {
     476                 :          0 :                 unloaded = TRUE;
     477                 :          0 :                 pa_module_unload_request(m, FALSE);
     478                 :            :             }
     479                 :            : 
     480         [ #  # ]:          0 :         if (unloaded == FALSE) {
     481                 :          0 :             pa_strbuf_printf(buf, "Module %s not loaded.\n", i);
     482                 :          0 :             return -1;
     483                 :            :         }
     484                 :            :     }
     485                 :            : 
     486                 :            :     return 0;
     487                 :            : }
     488                 :            : 
     489                 :          0 : static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     490                 :            :     const char *name;
     491                 :            :     pa_modinfo *i;
     492                 :            : 
     493                 :          0 :     pa_core_assert_ref(c);
     494         [ #  # ]:          0 :     pa_assert(t);
     495         [ #  # ]:          0 :     pa_assert(buf);
     496         [ #  # ]:          0 :     pa_assert(fail);
     497                 :            : 
     498         [ #  # ]:          0 :     if (!(name = pa_tokenizer_get(t, 1))) {
     499                 :          0 :         pa_strbuf_puts(buf, "You need to specify the module name.\n");
     500                 :          0 :         return -1;
     501                 :            :     }
     502                 :            : 
     503         [ #  # ]:          0 :     if ((i = pa_modinfo_get_by_name(name))) {
     504                 :            : 
     505                 :          0 :         pa_strbuf_printf(buf, "Name: %s\n", name);
     506                 :            : 
     507 [ #  # ][ #  # ]:          0 :         if (!i->description && !i->version && !i->author && !i->usage)
         [ #  # ][ #  # ]
     508                 :          0 :             pa_strbuf_printf(buf, "No module information available\n");
     509                 :            :         else {
     510         [ #  # ]:          0 :             if (i->version)
     511                 :          0 :                 pa_strbuf_printf(buf, "Version: %s\n", i->version);
     512         [ #  # ]:          0 :             if (i->description)
     513                 :          0 :                 pa_strbuf_printf(buf, "Description: %s\n", i->description);
     514         [ #  # ]:          0 :             if (i->author)
     515                 :          0 :                 pa_strbuf_printf(buf, "Author: %s\n", i->author);
     516         [ #  # ]:          0 :             if (i->usage)
     517                 :          0 :                 pa_strbuf_printf(buf, "Usage: %s\n", i->usage);
     518                 :          0 :             pa_strbuf_printf(buf, "Load Once: %s\n", pa_yes_no(i->load_once));
     519         [ #  # ]:          0 :             if (i->deprecated)
     520                 :          0 :                 pa_strbuf_printf(buf, "Warning, deprecated: %s\n", i->deprecated);
     521                 :            :         }
     522                 :            : 
     523                 :          0 :         pa_modinfo_free(i);
     524                 :            :     } else
     525                 :          0 :         pa_strbuf_puts(buf, "Failed to open module.\n");
     526                 :            : 
     527                 :            :     return 0;
     528                 :            : }
     529                 :            : 
     530                 :          0 : static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     531                 :            :     const char *n, *v;
     532                 :            :     pa_sink *sink;
     533                 :            :     uint32_t volume;
     534                 :            :     pa_cvolume cvolume;
     535                 :            : 
     536                 :          0 :     pa_core_assert_ref(c);
     537         [ #  # ]:          0 :     pa_assert(t);
     538         [ #  # ]:          0 :     pa_assert(buf);
     539         [ #  # ]:          0 :     pa_assert(fail);
     540                 :            : 
     541         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     542                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
     543                 :          0 :         return -1;
     544                 :            :     }
     545                 :            : 
     546         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
     547                 :          0 :         pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
     548                 :          0 :         return -1;
     549                 :            :     }
     550                 :            : 
     551         [ #  # ]:          0 :     if (pa_atou(v, &volume) < 0) {
     552                 :          0 :         pa_strbuf_puts(buf, "Failed to parse volume.\n");
     553                 :          0 :         return -1;
     554                 :            :     }
     555                 :            : 
     556         [ #  # ]:          0 :     if (!PA_VOLUME_IS_VALID(volume)) {
     557                 :          0 :         pa_strbuf_puts(buf, "Volume outside permissible range.\n");
     558                 :          0 :         return -1;
     559                 :            :     }
     560                 :            : 
     561         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
     562                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
     563                 :          0 :         return -1;
     564                 :            :     }
     565                 :            : 
     566                 :          0 :     pa_cvolume_set(&cvolume, 1, volume);
     567                 :          0 :     pa_sink_set_volume(sink, &cvolume, TRUE, TRUE);
     568                 :          0 :     return 0;
     569                 :            : }
     570                 :            : 
     571                 :          0 : static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     572                 :            :     const char *n, *v;
     573                 :            :     pa_sink_input *si;
     574                 :            :     pa_volume_t volume;
     575                 :            :     pa_cvolume cvolume;
     576                 :            :     uint32_t idx;
     577                 :            : 
     578                 :          0 :     pa_core_assert_ref(c);
     579         [ #  # ]:          0 :     pa_assert(t);
     580         [ #  # ]:          0 :     pa_assert(buf);
     581         [ #  # ]:          0 :     pa_assert(fail);
     582                 :            : 
     583         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     584                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
     585                 :          0 :         return -1;
     586                 :            :     }
     587                 :            : 
     588         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
     589                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
     590                 :          0 :         return -1;
     591                 :            :     }
     592                 :            : 
     593         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
     594                 :          0 :         pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
     595                 :          0 :         return -1;
     596                 :            :     }
     597                 :            : 
     598         [ #  # ]:          0 :     if (pa_atou(v, &volume) < 0) {
     599                 :          0 :         pa_strbuf_puts(buf, "Failed to parse volume.\n");
     600                 :          0 :         return -1;
     601                 :            :     }
     602                 :            : 
     603         [ #  # ]:          0 :     if (!PA_VOLUME_IS_VALID(volume)) {
     604                 :          0 :         pa_strbuf_puts(buf, "Volume outside permissible range.\n");
     605                 :          0 :         return -1;
     606                 :            :     }
     607                 :            : 
     608         [ #  # ]:          0 :     if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx))) {
     609                 :          0 :         pa_strbuf_puts(buf, "No sink input found with this index.\n");
     610                 :          0 :         return -1;
     611                 :            :     }
     612                 :            : 
     613         [ #  # ]:          0 :     if (!si->volume_writable) {
     614                 :          0 :         pa_strbuf_puts(buf, "This sink input's volume can't be changed.\n");
     615                 :          0 :         return -1;
     616                 :            :     }
     617                 :            : 
     618                 :          0 :     pa_cvolume_set(&cvolume, 1, volume);
     619                 :          0 :     pa_sink_input_set_volume(si, &cvolume, TRUE, TRUE);
     620                 :          0 :     return 0;
     621                 :            : }
     622                 :            : 
     623                 :          0 : static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     624                 :            :     const char *n, *v;
     625                 :            :     pa_source *source;
     626                 :            :     uint32_t volume;
     627                 :            :     pa_cvolume cvolume;
     628                 :            : 
     629                 :          0 :     pa_core_assert_ref(c);
     630         [ #  # ]:          0 :     pa_assert(t);
     631         [ #  # ]:          0 :     pa_assert(buf);
     632         [ #  # ]:          0 :     pa_assert(fail);
     633                 :            : 
     634         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     635                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
     636                 :          0 :         return -1;
     637                 :            :     }
     638                 :            : 
     639         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
     640                 :          0 :         pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
     641                 :          0 :         return -1;
     642                 :            :     }
     643                 :            : 
     644         [ #  # ]:          0 :     if (pa_atou(v, &volume) < 0) {
     645                 :          0 :         pa_strbuf_puts(buf, "Failed to parse volume.\n");
     646                 :          0 :         return -1;
     647                 :            :     }
     648                 :            : 
     649         [ #  # ]:          0 :     if (!PA_VOLUME_IS_VALID(volume)) {
     650                 :          0 :         pa_strbuf_puts(buf, "Volume outside permissible range.\n");
     651                 :          0 :         return -1;
     652                 :            :     }
     653                 :            : 
     654         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
     655                 :          0 :         pa_strbuf_puts(buf, "No source found by this name or index.\n");
     656                 :          0 :         return -1;
     657                 :            :     }
     658                 :            : 
     659                 :          0 :     pa_cvolume_set(&cvolume, 1, volume);
     660                 :          0 :     pa_source_set_volume(source, &cvolume, TRUE, TRUE);
     661                 :          0 :     return 0;
     662                 :            : }
     663                 :            : 
     664                 :          0 : static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     665                 :            :     const char *n, *v;
     666                 :            :     pa_source_output *so;
     667                 :            :     pa_volume_t volume;
     668                 :            :     pa_cvolume cvolume;
     669                 :            :     uint32_t idx;
     670                 :            : 
     671                 :          0 :     pa_core_assert_ref(c);
     672         [ #  # ]:          0 :     pa_assert(t);
     673         [ #  # ]:          0 :     pa_assert(buf);
     674         [ #  # ]:          0 :     pa_assert(fail);
     675                 :            : 
     676         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     677                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
     678                 :          0 :         return -1;
     679                 :            :     }
     680                 :            : 
     681         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
     682                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
     683                 :          0 :         return -1;
     684                 :            :     }
     685                 :            : 
     686         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
     687                 :          0 :         pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
     688                 :          0 :         return -1;
     689                 :            :     }
     690                 :            : 
     691         [ #  # ]:          0 :     if (pa_atou(v, &volume) < 0) {
     692                 :          0 :         pa_strbuf_puts(buf, "Failed to parse volume.\n");
     693                 :          0 :         return -1;
     694                 :            :     }
     695                 :            : 
     696         [ #  # ]:          0 :     if (!PA_VOLUME_IS_VALID(volume)) {
     697                 :          0 :         pa_strbuf_puts(buf, "Volume outside permissible range.\n");
     698                 :          0 :         return -1;
     699                 :            :     }
     700                 :            : 
     701         [ #  # ]:          0 :     if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) {
     702                 :          0 :         pa_strbuf_puts(buf, "No source output found with this index.\n");
     703                 :          0 :         return -1;
     704                 :            :     }
     705                 :            : 
     706         [ #  # ]:          0 :     if (!so->volume_writable) {
     707                 :          0 :         pa_strbuf_puts(buf, "This source output's volume can't be changed.\n");
     708                 :          0 :         return -1;
     709                 :            :     }
     710                 :            : 
     711                 :          0 :     pa_cvolume_set(&cvolume, 1, volume);
     712                 :          0 :     pa_source_output_set_volume(so, &cvolume, TRUE, TRUE);
     713                 :          0 :     return 0;
     714                 :            : }
     715                 :            : 
     716                 :          0 : static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     717                 :            :     const char *n, *m;
     718                 :            :     pa_sink *sink;
     719                 :            :     int mute;
     720                 :            : 
     721                 :          0 :     pa_core_assert_ref(c);
     722         [ #  # ]:          0 :     pa_assert(t);
     723         [ #  # ]:          0 :     pa_assert(buf);
     724         [ #  # ]:          0 :     pa_assert(fail);
     725                 :            : 
     726         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     727                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
     728                 :          0 :         return -1;
     729                 :            :     }
     730                 :            : 
     731         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 2))) {
     732                 :          0 :         pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
     733                 :          0 :         return -1;
     734                 :            :     }
     735                 :            : 
     736         [ #  # ]:          0 :     if ((mute = pa_parse_boolean(m)) < 0) {
     737                 :          0 :         pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
     738                 :          0 :         return -1;
     739                 :            :     }
     740                 :            : 
     741         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
     742                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
     743                 :          0 :         return -1;
     744                 :            :     }
     745                 :            : 
     746                 :          0 :     pa_sink_set_mute(sink, mute, TRUE);
     747                 :          0 :     return 0;
     748                 :            : }
     749                 :            : 
     750                 :          0 : static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     751                 :            :     const char *n, *m;
     752                 :            :     pa_source *source;
     753                 :            :     int mute;
     754                 :            : 
     755                 :          0 :     pa_core_assert_ref(c);
     756         [ #  # ]:          0 :     pa_assert(t);
     757         [ #  # ]:          0 :     pa_assert(buf);
     758         [ #  # ]:          0 :     pa_assert(fail);
     759                 :            : 
     760         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     761                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
     762                 :          0 :         return -1;
     763                 :            :     }
     764                 :            : 
     765         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 2))) {
     766                 :          0 :         pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
     767                 :          0 :         return -1;
     768                 :            :     }
     769                 :            : 
     770         [ #  # ]:          0 :     if ((mute = pa_parse_boolean(m)) < 0) {
     771                 :          0 :         pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
     772                 :          0 :         return -1;
     773                 :            :     }
     774                 :            : 
     775         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
     776                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
     777                 :          0 :         return -1;
     778                 :            :     }
     779                 :            : 
     780                 :          0 :     pa_source_set_mute(source, mute, TRUE);
     781                 :          0 :     return 0;
     782                 :            : }
     783                 :            : 
     784                 :          0 : static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     785                 :            :     const char *n, *s;
     786                 :            :     pa_sink *sink;
     787                 :            :     pa_proplist *p;
     788                 :            : 
     789                 :          0 :     pa_core_assert_ref(c);
     790         [ #  # ]:          0 :     pa_assert(t);
     791         [ #  # ]:          0 :     pa_assert(buf);
     792         [ #  # ]:          0 :     pa_assert(fail);
     793                 :            : 
     794         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     795                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
     796                 :          0 :         return -1;
     797                 :            :     }
     798                 :            : 
     799         [ #  # ]:          0 :     if (!(s = pa_tokenizer_get(t, 2))) {
     800                 :          0 :         pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
     801                 :          0 :         return -1;
     802                 :            :     }
     803                 :            : 
     804         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
     805                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
     806                 :          0 :         return -1;
     807                 :            :     }
     808                 :            : 
     809         [ #  # ]:          0 :     if (!(p = pa_proplist_from_string(s))) {
     810                 :          0 :         pa_strbuf_puts(buf, "Failed to parse proplist.\n");
     811                 :          0 :         return -1;
     812                 :            :     }
     813                 :            : 
     814                 :          0 :     pa_sink_update_proplist(sink, PA_UPDATE_REPLACE, p);
     815                 :            : 
     816                 :          0 :     pa_proplist_free(p);
     817                 :            : 
     818                 :          0 :     return 0;
     819                 :            : }
     820                 :            : 
     821                 :          0 : static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     822                 :            :     const char *n, *s;
     823                 :            :     pa_source *source;
     824                 :            :     pa_proplist *p;
     825                 :            : 
     826                 :          0 :     pa_core_assert_ref(c);
     827         [ #  # ]:          0 :     pa_assert(t);
     828         [ #  # ]:          0 :     pa_assert(buf);
     829         [ #  # ]:          0 :     pa_assert(fail);
     830                 :            : 
     831         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     832                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
     833                 :          0 :         return -1;
     834                 :            :     }
     835                 :            : 
     836         [ #  # ]:          0 :     if (!(s = pa_tokenizer_get(t, 2))) {
     837                 :          0 :         pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
     838                 :          0 :         return -1;
     839                 :            :     }
     840                 :            : 
     841         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
     842                 :          0 :         pa_strbuf_puts(buf, "No source found by this name or index.\n");
     843                 :          0 :         return -1;
     844                 :            :     }
     845                 :            : 
     846         [ #  # ]:          0 :     if (!(p = pa_proplist_from_string(s))) {
     847                 :          0 :         pa_strbuf_puts(buf, "Failed to parse proplist.\n");
     848                 :          0 :         return -1;
     849                 :            :     }
     850                 :            : 
     851                 :          0 :     pa_source_update_proplist(source, PA_UPDATE_REPLACE, p);
     852                 :            : 
     853                 :          0 :     pa_proplist_free(p);
     854                 :            : 
     855                 :          0 :     return 0;
     856                 :            : }
     857                 :            : 
     858                 :          0 : static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     859                 :            :     const char *n, *s;
     860                 :            :     pa_sink_input *si;
     861                 :            :     uint32_t idx;
     862                 :            :     pa_proplist *p;
     863                 :            : 
     864                 :          0 :     pa_core_assert_ref(c);
     865         [ #  # ]:          0 :     pa_assert(t);
     866         [ #  # ]:          0 :     pa_assert(buf);
     867         [ #  # ]:          0 :     pa_assert(fail);
     868                 :            : 
     869         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     870                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink input either by index.\n");
     871                 :          0 :         return -1;
     872                 :            :     }
     873                 :            : 
     874         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
     875                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
     876                 :          0 :         return -1;
     877                 :            :     }
     878                 :            : 
     879         [ #  # ]:          0 :     if (!(s = pa_tokenizer_get(t, 2))) {
     880                 :          0 :         pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
     881                 :          0 :         return -1;
     882                 :            :     }
     883                 :            : 
     884         [ #  # ]:          0 :     if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
     885                 :          0 :         pa_strbuf_puts(buf, "No sink input found with this index.\n");
     886                 :          0 :         return -1;
     887                 :            :     }
     888                 :            : 
     889         [ #  # ]:          0 :     if (!(p = pa_proplist_from_string(s))) {
     890                 :          0 :         pa_strbuf_puts(buf, "Failed to parse proplist.\n");
     891                 :          0 :         return -1;
     892                 :            :     }
     893                 :            : 
     894                 :          0 :     pa_sink_input_update_proplist(si, PA_UPDATE_REPLACE, p);
     895                 :            : 
     896                 :          0 :     pa_proplist_free(p);
     897                 :            : 
     898                 :          0 :     return 0;
     899                 :            : }
     900                 :            : 
     901                 :          0 : static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     902                 :            :     const char *n, *s;
     903                 :            :     pa_source_output *so;
     904                 :            :     uint32_t idx;
     905                 :            :     pa_proplist *p;
     906                 :            : 
     907                 :          0 :     pa_core_assert_ref(c);
     908         [ #  # ]:          0 :     pa_assert(t);
     909         [ #  # ]:          0 :     pa_assert(buf);
     910         [ #  # ]:          0 :     pa_assert(fail);
     911                 :            : 
     912         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     913                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
     914                 :          0 :         return -1;
     915                 :            :     }
     916                 :            : 
     917         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
     918                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
     919                 :          0 :         return -1;
     920                 :            :     }
     921                 :            : 
     922         [ #  # ]:          0 :     if (!(s = pa_tokenizer_get(t, 2))) {
     923                 :          0 :         pa_strbuf_puts(buf, "You need to specify a \"key=value\" argument.\n");
     924                 :          0 :         return -1;
     925                 :            :     }
     926                 :            : 
     927         [ #  # ]:          0 :     if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
     928                 :          0 :         pa_strbuf_puts(buf, "No source output found with this index.\n");
     929                 :          0 :         return -1;
     930                 :            :     }
     931                 :            : 
     932         [ #  # ]:          0 :     if (!(p = pa_proplist_from_string(s))) {
     933                 :          0 :         pa_strbuf_puts(buf, "Failed to parse proplist.\n");
     934                 :          0 :         return -1;
     935                 :            :     }
     936                 :            : 
     937                 :          0 :     pa_source_output_update_proplist(so, PA_UPDATE_REPLACE, p);
     938                 :            : 
     939                 :          0 :     pa_proplist_free(p);
     940                 :            : 
     941                 :          0 :     return 0;
     942                 :            : }
     943                 :            : 
     944                 :          0 : static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     945                 :            :     const char *n, *v;
     946                 :            :     pa_sink_input *si;
     947                 :            :     uint32_t idx;
     948                 :            :     int mute;
     949                 :            : 
     950                 :          0 :     pa_core_assert_ref(c);
     951         [ #  # ]:          0 :     pa_assert(t);
     952         [ #  # ]:          0 :     pa_assert(buf);
     953         [ #  # ]:          0 :     pa_assert(fail);
     954                 :            : 
     955         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     956                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
     957                 :          0 :         return -1;
     958                 :            :     }
     959                 :            : 
     960         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
     961                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
     962                 :          0 :         return -1;
     963                 :            :     }
     964                 :            : 
     965         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
     966                 :          0 :         pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
     967                 :          0 :         return -1;
     968                 :            :     }
     969                 :            : 
     970         [ #  # ]:          0 :     if ((mute = pa_parse_boolean(v)) < 0) {
     971                 :          0 :         pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
     972                 :          0 :         return -1;
     973                 :            :     }
     974                 :            : 
     975         [ #  # ]:          0 :     if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
     976                 :          0 :         pa_strbuf_puts(buf, "No sink input found with this index.\n");
     977                 :          0 :         return -1;
     978                 :            :     }
     979                 :            : 
     980                 :          0 :     pa_sink_input_set_mute(si, mute, TRUE);
     981                 :          0 :     return 0;
     982                 :            : }
     983                 :            : 
     984                 :          0 : static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     985                 :            :     const char *n, *v;
     986                 :            :     pa_source_output *so;
     987                 :            :     uint32_t idx;
     988                 :            :     int mute;
     989                 :            : 
     990                 :          0 :     pa_core_assert_ref(c);
     991         [ #  # ]:          0 :     pa_assert(t);
     992         [ #  # ]:          0 :     pa_assert(buf);
     993         [ #  # ]:          0 :     pa_assert(fail);
     994                 :            : 
     995         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
     996                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
     997                 :          0 :         return -1;
     998                 :            :     }
     999                 :            : 
    1000         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1001                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1002                 :          0 :         return -1;
    1003                 :            :     }
    1004                 :            : 
    1005         [ #  # ]:          0 :     if (!(v = pa_tokenizer_get(t, 2))) {
    1006                 :          0 :         pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
    1007                 :          0 :         return -1;
    1008                 :            :     }
    1009                 :            : 
    1010         [ #  # ]:          0 :     if ((mute = pa_parse_boolean(v)) < 0) {
    1011                 :          0 :         pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
    1012                 :          0 :         return -1;
    1013                 :            :     }
    1014                 :            : 
    1015         [ #  # ]:          0 :     if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
    1016                 :          0 :         pa_strbuf_puts(buf, "No source output found with this index.\n");
    1017                 :          0 :         return -1;
    1018                 :            :     }
    1019                 :            : 
    1020                 :          0 :     pa_source_output_set_mute(so, mute, TRUE);
    1021                 :          0 :     return 0;
    1022                 :            : }
    1023                 :            : 
    1024                 :          0 : static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1025                 :            :     const char *n;
    1026                 :            :     pa_sink *s;
    1027                 :            : 
    1028                 :          0 :     pa_core_assert_ref(c);
    1029         [ #  # ]:          0 :     pa_assert(t);
    1030         [ #  # ]:          0 :     pa_assert(buf);
    1031         [ #  # ]:          0 :     pa_assert(fail);
    1032                 :            : 
    1033         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1034                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
    1035                 :          0 :         return -1;
    1036                 :            :     }
    1037                 :            : 
    1038         [ #  # ]:          0 :     if ((s = pa_namereg_get(c, n, PA_NAMEREG_SINK)))
    1039                 :          0 :         pa_namereg_set_default_sink(c, s);
    1040                 :            :     else
    1041                 :          0 :         pa_strbuf_printf(buf, "Sink %s does not exist.\n", n);
    1042                 :            : 
    1043                 :            :     return 0;
    1044                 :            : }
    1045                 :            : 
    1046                 :          0 : static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1047                 :            :     const char *n;
    1048                 :            :     pa_source *s;
    1049                 :            : 
    1050                 :          0 :     pa_core_assert_ref(c);
    1051         [ #  # ]:          0 :     pa_assert(t);
    1052         [ #  # ]:          0 :     pa_assert(buf);
    1053         [ #  # ]:          0 :     pa_assert(fail);
    1054                 :            : 
    1055         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1056                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
    1057                 :          0 :         return -1;
    1058                 :            :     }
    1059                 :            : 
    1060         [ #  # ]:          0 :     if ((s = pa_namereg_get(c, n, PA_NAMEREG_SOURCE)))
    1061                 :          0 :         pa_namereg_set_default_source(c, s);
    1062                 :            :     else
    1063                 :          0 :         pa_strbuf_printf(buf, "Source %s does not exist.\n", n);
    1064                 :            :     return 0;
    1065                 :            : }
    1066                 :            : 
    1067                 :          0 : static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1068                 :            :     const char *n;
    1069                 :            :     pa_client *client;
    1070                 :            :     uint32_t idx;
    1071                 :            : 
    1072                 :          0 :     pa_core_assert_ref(c);
    1073         [ #  # ]:          0 :     pa_assert(t);
    1074         [ #  # ]:          0 :     pa_assert(buf);
    1075         [ #  # ]:          0 :     pa_assert(fail);
    1076                 :            : 
    1077         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1078                 :          0 :         pa_strbuf_puts(buf, "You need to specify a client by its index.\n");
    1079                 :          0 :         return -1;
    1080                 :            :     }
    1081                 :            : 
    1082         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1083                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1084                 :          0 :         return -1;
    1085                 :            :     }
    1086                 :            : 
    1087         [ #  # ]:          0 :     if (!(client = pa_idxset_get_by_index(c->clients, idx))) {
    1088                 :          0 :         pa_strbuf_puts(buf, "No client found by this index.\n");
    1089                 :          0 :         return -1;
    1090                 :            :     }
    1091                 :            : 
    1092                 :          0 :     pa_client_kill(client);
    1093                 :          0 :     return 0;
    1094                 :            : }
    1095                 :            : 
    1096                 :          0 : static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1097                 :            :     const char *n;
    1098                 :            :     pa_sink_input *sink_input;
    1099                 :            :     uint32_t idx;
    1100                 :            : 
    1101                 :          0 :     pa_core_assert_ref(c);
    1102         [ #  # ]:          0 :     pa_assert(t);
    1103         [ #  # ]:          0 :     pa_assert(buf);
    1104         [ #  # ]:          0 :     pa_assert(fail);
    1105                 :            : 
    1106         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1107                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
    1108                 :          0 :         return -1;
    1109                 :            :     }
    1110                 :            : 
    1111         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1112                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1113                 :          0 :         return -1;
    1114                 :            :     }
    1115                 :            : 
    1116         [ #  # ]:          0 :     if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) {
    1117                 :          0 :         pa_strbuf_puts(buf, "No sink input found by this index.\n");
    1118                 :          0 :         return -1;
    1119                 :            :     }
    1120                 :            : 
    1121                 :          0 :     pa_sink_input_kill(sink_input);
    1122                 :          0 :     return 0;
    1123                 :            : }
    1124                 :            : 
    1125                 :          0 : static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1126                 :            :     const char *n;
    1127                 :            :     pa_source_output *source_output;
    1128                 :            :     uint32_t idx;
    1129                 :            : 
    1130                 :          0 :     pa_core_assert_ref(c);
    1131         [ #  # ]:          0 :     pa_assert(t);
    1132         [ #  # ]:          0 :     pa_assert(buf);
    1133         [ #  # ]:          0 :     pa_assert(fail);
    1134                 :            : 
    1135         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1136                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
    1137                 :          0 :         return -1;
    1138                 :            :     }
    1139                 :            : 
    1140         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1141                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1142                 :          0 :         return -1;
    1143                 :            :     }
    1144                 :            : 
    1145         [ #  # ]:          0 :     if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) {
    1146                 :          0 :         pa_strbuf_puts(buf, "No source output found by this index.\n");
    1147                 :          0 :         return -1;
    1148                 :            :     }
    1149                 :            : 
    1150                 :          0 :     pa_source_output_kill(source_output);
    1151                 :          0 :     return 0;
    1152                 :            : }
    1153                 :            : 
    1154                 :          0 : static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1155                 :            :     char *s;
    1156                 :            : 
    1157                 :          0 :     pa_core_assert_ref(c);
    1158         [ #  # ]:          0 :     pa_assert(t);
    1159         [ #  # ]:          0 :     pa_assert(buf);
    1160         [ #  # ]:          0 :     pa_assert(fail);
    1161                 :            : 
    1162         [ #  # ]:          0 :     pa_assert_se(s = pa_scache_list_to_string(c));
    1163                 :          0 :     pa_strbuf_puts(buf, s);
    1164                 :          0 :     pa_xfree(s);
    1165                 :            : 
    1166                 :          0 :     return 0;
    1167                 :            : }
    1168                 :            : 
    1169                 :          0 : static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1170                 :            :     const char *n, *sink_name;
    1171                 :            :     pa_sink *sink;
    1172                 :            :     uint32_t idx;
    1173                 :            : 
    1174                 :          0 :     pa_core_assert_ref(c);
    1175         [ #  # ]:          0 :     pa_assert(t);
    1176         [ #  # ]:          0 :     pa_assert(buf);
    1177         [ #  # ]:          0 :     pa_assert(fail);
    1178                 :            : 
    1179 [ #  # ][ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
    1180                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n");
    1181                 :          0 :         return -1;
    1182                 :            :     }
    1183                 :            : 
    1184         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
    1185                 :          0 :         pa_strbuf_puts(buf, "No sink by that name.\n");
    1186                 :          0 :         return -1;
    1187                 :            :     }
    1188                 :            : 
    1189         [ #  # ]:          0 :     if (pa_scache_play_item(c, n, sink, PA_VOLUME_NORM, NULL, &idx) < 0) {
    1190                 :          0 :         pa_strbuf_puts(buf, "Failed to play sample.\n");
    1191                 :          0 :         return -1;
    1192                 :            :     }
    1193                 :            : 
    1194                 :          0 :     pa_strbuf_printf(buf, "Playing on sink input #%i\n", idx);
    1195                 :            : 
    1196                 :          0 :     return 0;
    1197                 :            : }
    1198                 :            : 
    1199                 :          0 : static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1200                 :            :     const char *n;
    1201                 :            : 
    1202                 :          0 :     pa_core_assert_ref(c);
    1203         [ #  # ]:          0 :     pa_assert(t);
    1204         [ #  # ]:          0 :     pa_assert(buf);
    1205         [ #  # ]:          0 :     pa_assert(fail);
    1206                 :            : 
    1207         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1208                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sample name.\n");
    1209                 :          0 :         return -1;
    1210                 :            :     }
    1211                 :            : 
    1212         [ #  # ]:          0 :     if (pa_scache_remove_item(c, n) < 0) {
    1213                 :          0 :         pa_strbuf_puts(buf, "Failed to remove sample.\n");
    1214                 :          0 :         return -1;
    1215                 :            :     }
    1216                 :            : 
    1217                 :            :     return 0;
    1218                 :            : }
    1219                 :            : 
    1220                 :          0 : static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1221                 :            :     const char *fname, *n;
    1222                 :            :     int r;
    1223                 :            : 
    1224                 :          0 :     pa_core_assert_ref(c);
    1225         [ #  # ]:          0 :     pa_assert(t);
    1226         [ #  # ]:          0 :     pa_assert(buf);
    1227         [ #  # ]:          0 :     pa_assert(fail);
    1228                 :            : 
    1229 [ #  # ][ #  # ]:          0 :     if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) {
    1230                 :          0 :         pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n");
    1231                 :          0 :         return -1;
    1232                 :            :     }
    1233                 :            : 
    1234         [ #  # ]:          0 :     if (strstr(pa_tokenizer_get(t, 0), "lazy"))
    1235                 :          0 :         r = pa_scache_add_file_lazy(c, n, fname, NULL);
    1236                 :            :     else
    1237                 :          0 :         r = pa_scache_add_file(c, n, fname, NULL);
    1238                 :            : 
    1239         [ #  # ]:          0 :     if (r < 0)
    1240                 :          0 :         pa_strbuf_puts(buf, "Failed to load sound file.\n");
    1241                 :            : 
    1242                 :            :     return 0;
    1243                 :            : }
    1244                 :            : 
    1245                 :          0 : static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1246                 :            :     const char *pname;
    1247                 :            : 
    1248                 :          0 :     pa_core_assert_ref(c);
    1249         [ #  # ]:          0 :     pa_assert(t);
    1250         [ #  # ]:          0 :     pa_assert(buf);
    1251         [ #  # ]:          0 :     pa_assert(fail);
    1252                 :            : 
    1253         [ #  # ]:          0 :     if (!(pname = pa_tokenizer_get(t, 1))) {
    1254                 :          0 :         pa_strbuf_puts(buf, "You need to specify a path name.\n");
    1255                 :          0 :         return -1;
    1256                 :            :     }
    1257                 :            : 
    1258         [ #  # ]:          0 :     if (pa_scache_add_directory_lazy(c, pname) < 0) {
    1259                 :          0 :         pa_strbuf_puts(buf, "Failed to load directory.\n");
    1260                 :          0 :         return -1;
    1261                 :            :     }
    1262                 :            : 
    1263                 :            :     return 0;
    1264                 :            : }
    1265                 :            : 
    1266                 :          0 : static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1267                 :            :     const char *fname, *sink_name;
    1268                 :            :     pa_sink *sink;
    1269                 :            : 
    1270                 :          0 :     pa_core_assert_ref(c);
    1271         [ #  # ]:          0 :     pa_assert(t);
    1272         [ #  # ]:          0 :     pa_assert(buf);
    1273         [ #  # ]:          0 :     pa_assert(fail);
    1274                 :            : 
    1275 [ #  # ][ #  # ]:          0 :     if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) {
    1276                 :          0 :         pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n");
    1277                 :          0 :         return -1;
    1278                 :            :     }
    1279                 :            : 
    1280         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK))) {
    1281                 :          0 :         pa_strbuf_puts(buf, "No sink by that name.\n");
    1282                 :          0 :         return -1;
    1283                 :            :     }
    1284                 :            : 
    1285                 :            : 
    1286                 :          0 :     return pa_play_file(sink, fname, NULL);
    1287                 :            : }
    1288                 :            : 
    1289                 :          0 : static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1290                 :          0 :     pa_core_assert_ref(c);
    1291         [ #  # ]:          0 :     pa_assert(t);
    1292         [ #  # ]:          0 :     pa_assert(buf);
    1293         [ #  # ]:          0 :     pa_assert(fail);
    1294                 :            : 
    1295                 :          0 :     pa_shared_dump(c, buf);
    1296                 :          0 :     return 0;
    1297                 :            : }
    1298                 :            : 
    1299                 :          0 : static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1300                 :          0 :     pa_core_assert_ref(c);
    1301         [ #  # ]:          0 :     pa_assert(t);
    1302         [ #  # ]:          0 :     pa_assert(buf);
    1303         [ #  # ]:          0 :     pa_assert(fail);
    1304                 :            : 
    1305                 :          0 :     pa_mempool_vacuum(c->mempool);
    1306                 :            : 
    1307                 :          0 :     return 0;
    1308                 :            : }
    1309                 :            : 
    1310                 :          0 : static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1311                 :            :     const char *n, *k;
    1312                 :            :     pa_sink_input *si;
    1313                 :            :     pa_sink *sink;
    1314                 :            :     uint32_t idx;
    1315                 :            : 
    1316                 :          0 :     pa_core_assert_ref(c);
    1317         [ #  # ]:          0 :     pa_assert(t);
    1318         [ #  # ]:          0 :     pa_assert(buf);
    1319         [ #  # ]:          0 :     pa_assert(fail);
    1320                 :            : 
    1321         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1322                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n");
    1323                 :          0 :         return -1;
    1324                 :            :     }
    1325                 :            : 
    1326         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1327                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1328                 :          0 :         return -1;
    1329                 :            :     }
    1330                 :            : 
    1331         [ #  # ]:          0 :     if (!(k = pa_tokenizer_get(t, 2))) {
    1332                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink.\n");
    1333                 :          0 :         return -1;
    1334                 :            :     }
    1335                 :            : 
    1336         [ #  # ]:          0 :     if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
    1337                 :          0 :         pa_strbuf_puts(buf, "No sink input found with this index.\n");
    1338                 :          0 :         return -1;
    1339                 :            :     }
    1340                 :            : 
    1341         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, k, PA_NAMEREG_SINK))) {
    1342                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
    1343                 :          0 :         return -1;
    1344                 :            :     }
    1345                 :            : 
    1346         [ #  # ]:          0 :     if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
    1347                 :          0 :         pa_strbuf_puts(buf, "Moved failed.\n");
    1348                 :          0 :         return -1;
    1349                 :            :     }
    1350                 :            :     return 0;
    1351                 :            : }
    1352                 :            : 
    1353                 :          0 : static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1354                 :            :     const char *n, *k;
    1355                 :            :     pa_source_output *so;
    1356                 :            :     pa_source *source;
    1357                 :            :     uint32_t idx;
    1358                 :            : 
    1359                 :          0 :     pa_core_assert_ref(c);
    1360         [ #  # ]:          0 :     pa_assert(t);
    1361         [ #  # ]:          0 :     pa_assert(buf);
    1362         [ #  # ]:          0 :     pa_assert(fail);
    1363                 :            : 
    1364         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1365                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
    1366                 :          0 :         return -1;
    1367                 :            :     }
    1368                 :            : 
    1369         [ #  # ]:          0 :     if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
    1370                 :          0 :         pa_strbuf_puts(buf, "Failed to parse index.\n");
    1371                 :          0 :         return -1;
    1372                 :            :     }
    1373                 :            : 
    1374         [ #  # ]:          0 :     if (!(k = pa_tokenizer_get(t, 2))) {
    1375                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source.\n");
    1376                 :          0 :         return -1;
    1377                 :            :     }
    1378                 :            : 
    1379         [ #  # ]:          0 :     if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
    1380                 :          0 :         pa_strbuf_puts(buf, "No source output found with this index.\n");
    1381                 :          0 :         return -1;
    1382                 :            :     }
    1383                 :            : 
    1384         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, k, PA_NAMEREG_SOURCE))) {
    1385                 :          0 :         pa_strbuf_puts(buf, "No source found by this name or index.\n");
    1386                 :          0 :         return -1;
    1387                 :            :     }
    1388                 :            : 
    1389         [ #  # ]:          0 :     if (pa_source_output_move_to(so, source, TRUE) < 0) {
    1390                 :          0 :         pa_strbuf_puts(buf, "Moved failed.\n");
    1391                 :          0 :         return -1;
    1392                 :            :     }
    1393                 :            :     return 0;
    1394                 :            : }
    1395                 :            : 
    1396                 :          0 : static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1397                 :            :     const char *n, *m;
    1398                 :            :     pa_sink *sink;
    1399                 :            :     int suspend, r;
    1400                 :            : 
    1401                 :          0 :     pa_core_assert_ref(c);
    1402         [ #  # ]:          0 :     pa_assert(t);
    1403         [ #  # ]:          0 :     pa_assert(buf);
    1404         [ #  # ]:          0 :     pa_assert(fail);
    1405                 :            : 
    1406         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1407                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
    1408                 :          0 :         return -1;
    1409                 :            :     }
    1410                 :            : 
    1411         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 2))) {
    1412                 :          0 :         pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
    1413                 :          0 :         return -1;
    1414                 :            :     }
    1415                 :            : 
    1416         [ #  # ]:          0 :     if ((suspend = pa_parse_boolean(m)) < 0) {
    1417                 :          0 :         pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
    1418                 :          0 :         return -1;
    1419                 :            :     }
    1420                 :            : 
    1421         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
    1422                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
    1423                 :          0 :         return -1;
    1424                 :            :     }
    1425                 :            : 
    1426         [ #  # ]:          0 :     if ((r = pa_sink_suspend(sink, suspend, PA_SUSPEND_USER)) < 0)
    1427                 :          0 :         pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r));
    1428                 :            : 
    1429                 :            :     return 0;
    1430                 :            : }
    1431                 :            : 
    1432                 :          0 : static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1433                 :            :     const char *n, *m;
    1434                 :            :     pa_source *source;
    1435                 :            :     int suspend, r;
    1436                 :            : 
    1437                 :          0 :     pa_core_assert_ref(c);
    1438         [ #  # ]:          0 :     pa_assert(t);
    1439         [ #  # ]:          0 :     pa_assert(buf);
    1440         [ #  # ]:          0 :     pa_assert(fail);
    1441                 :            : 
    1442         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1443                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
    1444                 :          0 :         return -1;
    1445                 :            :     }
    1446                 :            : 
    1447         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 2))) {
    1448                 :          0 :         pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
    1449                 :          0 :         return -1;
    1450                 :            :     }
    1451                 :            : 
    1452         [ #  # ]:          0 :     if ((suspend = pa_parse_boolean(m)) < 0) {
    1453                 :          0 :         pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
    1454                 :          0 :         return -1;
    1455                 :            :     }
    1456                 :            : 
    1457         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
    1458                 :          0 :         pa_strbuf_puts(buf, "No source found by this name or index.\n");
    1459                 :          0 :         return -1;
    1460                 :            :     }
    1461                 :            : 
    1462         [ #  # ]:          0 :     if ((r = pa_source_suspend(source, suspend, PA_SUSPEND_USER)) < 0)
    1463                 :          0 :         pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r));
    1464                 :            : 
    1465                 :            :     return 0;
    1466                 :            : }
    1467                 :            : 
    1468                 :          0 : static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1469                 :            :     const char *m;
    1470                 :            :     int suspend, r;
    1471                 :            : 
    1472                 :          0 :     pa_core_assert_ref(c);
    1473         [ #  # ]:          0 :     pa_assert(t);
    1474         [ #  # ]:          0 :     pa_assert(buf);
    1475         [ #  # ]:          0 :     pa_assert(fail);
    1476                 :            : 
    1477         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1478                 :          0 :         pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n");
    1479                 :          0 :         return -1;
    1480                 :            :     }
    1481                 :            : 
    1482         [ #  # ]:          0 :     if ((suspend = pa_parse_boolean(m)) < 0) {
    1483                 :          0 :         pa_strbuf_puts(buf, "Failed to parse suspend switch.\n");
    1484                 :          0 :         return -1;
    1485                 :            :     }
    1486                 :            : 
    1487         [ #  # ]:          0 :     if ((r = pa_sink_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
    1488                 :          0 :         pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r));
    1489                 :            : 
    1490         [ #  # ]:          0 :     if ((r = pa_source_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
    1491                 :          0 :         pa_strbuf_printf(buf, "Failed to resume/suspend all sources: %s\n", pa_strerror(r));
    1492                 :            : 
    1493                 :            :     return 0;
    1494                 :            : }
    1495                 :            : 
    1496                 :          0 : static int pa_cli_command_log_target(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1497                 :            :     const char *m;
    1498                 :            : 
    1499                 :          0 :     pa_core_assert_ref(c);
    1500         [ #  # ]:          0 :     pa_assert(t);
    1501         [ #  # ]:          0 :     pa_assert(buf);
    1502         [ #  # ]:          0 :     pa_assert(fail);
    1503                 :            : 
    1504         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1505                 :          0 :         pa_strbuf_puts(buf, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
    1506                 :          0 :         return -1;
    1507                 :            :     }
    1508                 :            : 
    1509         [ #  # ]:          0 :     if (pa_streq(m, "null"))
    1510                 :          0 :         pa_log_set_target(PA_LOG_NULL);
    1511         [ #  # ]:          0 :     else if (pa_streq(m, "syslog"))
    1512                 :          0 :         pa_log_set_target(PA_LOG_SYSLOG);
    1513 [ #  # ][ #  # ]:          0 :     else if (pa_streq(m, "stderr") || pa_streq(m, "auto")) {
    1514                 :            :         /* 'auto' is actually the effect with 'stderr' */
    1515                 :          0 :         pa_log_set_target(PA_LOG_STDERR);
    1516         [ #  # ]:          0 :     } else if (pa_startswith(m, "file:")) {
    1517                 :          0 :         const char *file_path = m + 5;
    1518                 :            :         int log_fd;
    1519                 :            : 
    1520                 :            :         /* Open target file with user rights */
    1521         [ #  # ]:          0 :         if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
    1522                 :          0 :             pa_log_set_target(PA_LOG_FD);
    1523                 :          0 :             pa_log_set_fd(log_fd);
    1524                 :            :         } else {
    1525                 :          0 :             pa_strbuf_printf(buf, "Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
    1526                 :          0 :             return -1;
    1527                 :            :         }
    1528                 :            :     } else {
    1529                 :          0 :         pa_strbuf_puts(buf, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
    1530                 :          0 :         return -1;
    1531                 :            :     }
    1532                 :            : 
    1533                 :            :     return 0;
    1534                 :            : }
    1535                 :            : 
    1536                 :          0 : static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1537                 :            :     const char *m;
    1538                 :            :     uint32_t level;
    1539                 :            : 
    1540                 :          0 :     pa_core_assert_ref(c);
    1541         [ #  # ]:          0 :     pa_assert(t);
    1542         [ #  # ]:          0 :     pa_assert(buf);
    1543         [ #  # ]:          0 :     pa_assert(fail);
    1544                 :            : 
    1545         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1546                 :          0 :         pa_strbuf_puts(buf, "You need to specify a log level (0..4).\n");
    1547                 :          0 :         return -1;
    1548                 :            :     }
    1549                 :            : 
    1550 [ #  # ][ #  # ]:          0 :     if (pa_atou(m, &level) < 0 || level >= PA_LOG_LEVEL_MAX) {
    1551                 :          0 :         pa_strbuf_puts(buf, "Failed to parse log level.\n");
    1552                 :          0 :         return -1;
    1553                 :            :     }
    1554                 :            : 
    1555                 :          0 :     pa_log_set_level(level);
    1556                 :            : 
    1557                 :          0 :     return 0;
    1558                 :            : }
    1559                 :            : 
    1560                 :          0 : static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1561                 :            :     const char *m;
    1562                 :            :     pa_bool_t b;
    1563                 :            : 
    1564                 :          0 :     pa_core_assert_ref(c);
    1565         [ #  # ]:          0 :     pa_assert(t);
    1566         [ #  # ]:          0 :     pa_assert(buf);
    1567         [ #  # ]:          0 :     pa_assert(fail);
    1568                 :            : 
    1569         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1570                 :          0 :         pa_strbuf_puts(buf, "You need to specify a boolean.\n");
    1571                 :          0 :         return -1;
    1572                 :            :     }
    1573                 :            : 
    1574         [ #  # ]:          0 :     if ((b = pa_parse_boolean(m)) < 0) {
    1575                 :          0 :         pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
    1576                 :          0 :         return -1;
    1577                 :            :     }
    1578                 :            : 
    1579         [ #  # ]:          0 :     pa_log_set_flags(PA_LOG_PRINT_META, b ? PA_LOG_SET : PA_LOG_UNSET);
    1580                 :            : 
    1581                 :          0 :     return 0;
    1582                 :            : }
    1583                 :            : 
    1584                 :          0 : static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1585                 :            :     const char *m;
    1586                 :            :     pa_bool_t b;
    1587                 :            : 
    1588                 :          0 :     pa_core_assert_ref(c);
    1589         [ #  # ]:          0 :     pa_assert(t);
    1590         [ #  # ]:          0 :     pa_assert(buf);
    1591         [ #  # ]:          0 :     pa_assert(fail);
    1592                 :            : 
    1593         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1594                 :          0 :         pa_strbuf_puts(buf, "You need to specify a boolean.\n");
    1595                 :          0 :         return -1;
    1596                 :            :     }
    1597                 :            : 
    1598         [ #  # ]:          0 :     if ((b = pa_parse_boolean(m)) < 0) {
    1599                 :          0 :         pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
    1600                 :          0 :         return -1;
    1601                 :            :     }
    1602                 :            : 
    1603         [ #  # ]:          0 :     pa_log_set_flags(PA_LOG_PRINT_TIME, b ? PA_LOG_SET : PA_LOG_UNSET);
    1604                 :            : 
    1605                 :          0 :     return 0;
    1606                 :            : }
    1607                 :            : 
    1608                 :          0 : static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1609                 :            :     const char *m;
    1610                 :            :     uint32_t nframes;
    1611                 :            : 
    1612                 :          0 :     pa_core_assert_ref(c);
    1613         [ #  # ]:          0 :     pa_assert(t);
    1614         [ #  # ]:          0 :     pa_assert(buf);
    1615         [ #  # ]:          0 :     pa_assert(fail);
    1616                 :            : 
    1617         [ #  # ]:          0 :     if (!(m = pa_tokenizer_get(t, 1))) {
    1618                 :          0 :         pa_strbuf_puts(buf, "You need to specify a backtrace level.\n");
    1619                 :          0 :         return -1;
    1620                 :            :     }
    1621                 :            : 
    1622 [ #  # ][ #  # ]:          0 :     if (pa_atou(m, &nframes) < 0 || nframes >= 1000) {
    1623                 :          0 :         pa_strbuf_puts(buf, "Failed to parse backtrace level.\n");
    1624                 :          0 :         return -1;
    1625                 :            :     }
    1626                 :            : 
    1627                 :          0 :     pa_log_set_show_backtrace(nframes);
    1628                 :            : 
    1629                 :          0 :     return 0;
    1630                 :            : }
    1631                 :            : 
    1632                 :          0 : static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1633                 :            :     const char *n, *p;
    1634                 :            :     pa_card *card;
    1635                 :            : 
    1636                 :          0 :     pa_core_assert_ref(c);
    1637         [ #  # ]:          0 :     pa_assert(t);
    1638         [ #  # ]:          0 :     pa_assert(buf);
    1639         [ #  # ]:          0 :     pa_assert(fail);
    1640                 :            : 
    1641         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1642                 :          0 :         pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
    1643                 :          0 :         return -1;
    1644                 :            :     }
    1645                 :            : 
    1646         [ #  # ]:          0 :     if (!(p = pa_tokenizer_get(t, 2))) {
    1647                 :          0 :         pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
    1648                 :          0 :         return -1;
    1649                 :            :     }
    1650                 :            : 
    1651         [ #  # ]:          0 :     if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
    1652                 :          0 :         pa_strbuf_puts(buf, "No card found by this name or index.\n");
    1653                 :          0 :         return -1;
    1654                 :            :     }
    1655                 :            : 
    1656         [ #  # ]:          0 :     if (pa_card_set_profile(card, p, TRUE) < 0) {
    1657                 :          0 :         pa_strbuf_printf(buf, "Failed to set card profile to '%s'.\n", p);
    1658                 :          0 :         return -1;
    1659                 :            :     }
    1660                 :            : 
    1661                 :            :     return 0;
    1662                 :            : }
    1663                 :            : 
    1664                 :          0 : static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1665                 :            :     const char *n, *p;
    1666                 :            :     pa_sink *sink;
    1667                 :            : 
    1668                 :          0 :     pa_core_assert_ref(c);
    1669         [ #  # ]:          0 :     pa_assert(t);
    1670         [ #  # ]:          0 :     pa_assert(buf);
    1671         [ #  # ]:          0 :     pa_assert(fail);
    1672                 :            : 
    1673         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1674                 :          0 :         pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n");
    1675                 :          0 :         return -1;
    1676                 :            :     }
    1677                 :            : 
    1678         [ #  # ]:          0 :     if (!(p = pa_tokenizer_get(t, 2))) {
    1679                 :          0 :         pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
    1680                 :          0 :         return -1;
    1681                 :            :     }
    1682                 :            : 
    1683         [ #  # ]:          0 :     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
    1684                 :          0 :         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
    1685                 :          0 :         return -1;
    1686                 :            :     }
    1687                 :            : 
    1688         [ #  # ]:          0 :     if (pa_sink_set_port(sink, p, TRUE) < 0) {
    1689                 :          0 :         pa_strbuf_printf(buf, "Failed to set sink port to '%s'.\n", p);
    1690                 :          0 :         return -1;
    1691                 :            :     }
    1692                 :            : 
    1693                 :            :     return 0;
    1694                 :            : }
    1695                 :            : 
    1696                 :          0 : static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1697                 :            :     const char *n, *p;
    1698                 :            :     pa_source *source;
    1699                 :            : 
    1700                 :          0 :     pa_core_assert_ref(c);
    1701         [ #  # ]:          0 :     pa_assert(t);
    1702         [ #  # ]:          0 :     pa_assert(buf);
    1703         [ #  # ]:          0 :     pa_assert(fail);
    1704                 :            : 
    1705         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1706                 :          0 :         pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n");
    1707                 :          0 :         return -1;
    1708                 :            :     }
    1709                 :            : 
    1710         [ #  # ]:          0 :     if (!(p = pa_tokenizer_get(t, 2))) {
    1711                 :          0 :         pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
    1712                 :          0 :         return -1;
    1713                 :            :     }
    1714                 :            : 
    1715         [ #  # ]:          0 :     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
    1716                 :          0 :         pa_strbuf_puts(buf, "No source found by this name or index.\n");
    1717                 :          0 :         return -1;
    1718                 :            :     }
    1719                 :            : 
    1720         [ #  # ]:          0 :     if (pa_source_set_port(source, p, TRUE) < 0) {
    1721                 :          0 :         pa_strbuf_printf(buf, "Failed to set source port to '%s'.\n", p);
    1722                 :          0 :         return -1;
    1723                 :            :     }
    1724                 :            : 
    1725                 :            :     return 0;
    1726                 :            : }
    1727                 :            : 
    1728                 :          0 : static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1729                 :            :     const char *n, *p, *l;
    1730                 :            :     pa_device_port *port;
    1731                 :            :     pa_card *card;
    1732                 :            :     int32_t offset;
    1733                 :            : 
    1734                 :          0 :     pa_core_assert_ref(c);
    1735         [ #  # ]:          0 :     pa_assert(t);
    1736         [ #  # ]:          0 :     pa_assert(buf);
    1737         [ #  # ]:          0 :     pa_assert(fail);
    1738                 :            : 
    1739         [ #  # ]:          0 :     if (!(n = pa_tokenizer_get(t, 1))) {
    1740                 :          0 :         pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
    1741                 :          0 :         return -1;
    1742                 :            :     }
    1743                 :            : 
    1744         [ #  # ]:          0 :     if (!(p = pa_tokenizer_get(t, 2))) {
    1745                 :          0 :         pa_strbuf_puts(buf, "You need to specify a port by its name.\n");
    1746                 :          0 :         return -1;
    1747                 :            :     }
    1748                 :            : 
    1749         [ #  # ]:          0 :     if (!(l = pa_tokenizer_get(t, 3))) {
    1750                 :          0 :         pa_strbuf_puts(buf, "You need to specify a latency offset.\n");
    1751                 :          0 :         return -1;
    1752                 :            :     }
    1753                 :            : 
    1754         [ #  # ]:          0 :     if (pa_atoi(l, &offset) < 0) {
    1755                 :          0 :         pa_strbuf_puts(buf, "Failed to parse the latency offset.\n");
    1756                 :          0 :         return -1;
    1757                 :            :     }
    1758                 :            : 
    1759         [ #  # ]:          0 :     if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
    1760                 :          0 :         pa_strbuf_puts(buf, "No card found by this name or index.\n");
    1761                 :          0 :         return -1;
    1762                 :            :     }
    1763                 :            : 
    1764         [ #  # ]:          0 :     if (!(port = pa_hashmap_get(card->ports, p))) {
    1765                 :          0 :         pa_strbuf_puts(buf, "No port found by this name.\n");
    1766                 :          0 :         return -1;
    1767                 :            :     }
    1768                 :            : 
    1769                 :          0 :     pa_device_port_set_latency_offset(port, offset);
    1770                 :            : 
    1771                 :          0 :     return 0;
    1772                 :            : }
    1773                 :            : 
    1774                 :          0 : static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1775                 :            :     pa_module *m;
    1776                 :            :     pa_sink *sink;
    1777                 :            :     pa_source *source;
    1778                 :            :     pa_card *card;
    1779                 :            :     pa_bool_t nl;
    1780                 :            :     uint32_t idx;
    1781                 :            :     time_t now;
    1782                 :            : #ifdef HAVE_CTIME_R
    1783                 :            :     char txt[256];
    1784                 :            : #endif
    1785                 :            : 
    1786                 :          0 :     pa_core_assert_ref(c);
    1787         [ #  # ]:          0 :     pa_assert(t);
    1788         [ #  # ]:          0 :     pa_assert(buf);
    1789         [ #  # ]:          0 :     pa_assert(fail);
    1790                 :            : 
    1791                 :          0 :     time(&now);
    1792                 :            : 
    1793                 :            : #ifdef HAVE_CTIME_R
    1794                 :          0 :     pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt));
    1795                 :            : #else
    1796                 :            :     pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now));
    1797                 :            : #endif
    1798                 :            : 
    1799         [ #  # ]:          0 :     PA_IDXSET_FOREACH(m, c->modules, idx) {
    1800                 :            : 
    1801                 :          0 :         pa_strbuf_printf(buf, "load-module %s", m->name);
    1802                 :            : 
    1803         [ #  # ]:          0 :         if (m->argument)
    1804                 :          0 :             pa_strbuf_printf(buf, " %s", m->argument);
    1805                 :            : 
    1806                 :          0 :         pa_strbuf_puts(buf, "\n");
    1807                 :            :     }
    1808                 :            : 
    1809                 :          0 :     nl = FALSE;
    1810         [ #  # ]:          0 :     PA_IDXSET_FOREACH(sink, c->sinks, idx) {
    1811                 :            : 
    1812         [ #  # ]:          0 :         if (!nl) {
    1813                 :          0 :             pa_strbuf_puts(buf, "\n");
    1814                 :          0 :             nl = TRUE;
    1815                 :            :         }
    1816                 :            : 
    1817                 :          0 :         pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_max(pa_sink_get_volume(sink, FALSE)));
    1818                 :          0 :         pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
    1819                 :          0 :         pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
    1820                 :            :     }
    1821                 :            : 
    1822                 :          0 :     nl = FALSE;
    1823         [ #  # ]:          0 :     PA_IDXSET_FOREACH(source, c->sources, idx) {
    1824                 :            : 
    1825         [ #  # ]:          0 :         if (!nl) {
    1826                 :          0 :             pa_strbuf_puts(buf, "\n");
    1827                 :          0 :             nl = TRUE;
    1828                 :            :         }
    1829                 :            : 
    1830                 :          0 :         pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_max(pa_source_get_volume(source, FALSE)));
    1831                 :          0 :         pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
    1832                 :          0 :         pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
    1833                 :            :     }
    1834                 :            : 
    1835                 :          0 :     nl = FALSE;
    1836         [ #  # ]:          0 :     PA_IDXSET_FOREACH(card, c->cards, idx) {
    1837                 :            : 
    1838         [ #  # ]:          0 :         if (!nl) {
    1839                 :          0 :             pa_strbuf_puts(buf, "\n");
    1840                 :          0 :             nl = TRUE;
    1841                 :            :         }
    1842                 :            : 
    1843                 :          0 :         pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
    1844                 :            :     }
    1845                 :            : 
    1846                 :          0 :     nl = FALSE;
    1847         [ #  # ]:          0 :     if ((sink = pa_namereg_get_default_sink(c))) {
    1848                 :            :         if (!nl) {
    1849                 :          0 :             pa_strbuf_puts(buf, "\n");
    1850                 :          0 :             nl = TRUE;
    1851                 :            :         }
    1852                 :            : 
    1853                 :          0 :         pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name);
    1854                 :            :     }
    1855                 :            : 
    1856         [ #  # ]:          0 :     if ((source = pa_namereg_get_default_source(c))) {
    1857         [ #  # ]:          0 :         if (!nl)
    1858                 :          0 :             pa_strbuf_puts(buf, "\n");
    1859                 :            : 
    1860                 :          0 :         pa_strbuf_printf(buf, "set-default-source %s\n", source->name);
    1861                 :            :     }
    1862                 :            : 
    1863                 :          0 :     pa_strbuf_puts(buf, "\n### EOF\n");
    1864                 :            : 
    1865                 :          0 :     return 0;
    1866                 :            : }
    1867                 :            : 
    1868                 :          0 : static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
    1869                 :            :     pa_sink *s;
    1870                 :            :     pa_source *so;
    1871                 :            :     pa_sink_input *i;
    1872                 :            :     pa_source_output *o;
    1873                 :            :     uint32_t s_idx, i_idx;
    1874                 :            :     char v_str[PA_CVOLUME_SNPRINT_MAX];
    1875                 :            : 
    1876                 :          0 :     pa_core_assert_ref(c);
    1877         [ #  # ]:          0 :     pa_assert(t);
    1878         [ #  # ]:          0 :     pa_assert(buf);
    1879         [ #  # ]:          0 :     pa_assert(fail);
    1880                 :            : 
    1881         [ #  # ]:          0 :     PA_IDXSET_FOREACH(s, c->sinks, s_idx) {
    1882                 :          0 :         pa_strbuf_printf(buf, "Sink %d: ", s_idx);
    1883                 :          0 :         pa_strbuf_printf(buf, "reference = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->reference_volume));
    1884                 :          0 :         pa_strbuf_printf(buf, "real = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->real_volume));
    1885                 :          0 :         pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->soft_volume));
    1886                 :          0 :         pa_strbuf_printf(buf, "current_hw = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->thread_info.current_hw_volume));
    1887                 :          0 :         pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(s->save_volume));
    1888                 :            : 
    1889         [ #  # ]:          0 :         PA_IDXSET_FOREACH(i, s->inputs, i_idx) {
    1890                 :          0 :             pa_strbuf_printf(buf, "\tInput %d: ", i_idx);
    1891                 :          0 :             pa_strbuf_printf(buf, "volume = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume));
    1892                 :          0 :             pa_strbuf_printf(buf, "reference_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->reference_ratio));
    1893                 :          0 :             pa_strbuf_printf(buf, "real_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->real_ratio));
    1894                 :          0 :             pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->soft_volume));
    1895                 :          0 :             pa_strbuf_printf(buf, "volume_factor = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume_factor));
    1896                 :          0 :             pa_strbuf_printf(buf, "volume_factor_sink = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume_factor_sink));
    1897                 :          0 :             pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(i->save_volume));
    1898                 :            :         }
    1899                 :            :     }
    1900                 :            : 
    1901         [ #  # ]:          0 :     PA_IDXSET_FOREACH(so, c->sources, s_idx) {
    1902                 :          0 :         pa_strbuf_printf(buf, "Source %d: ", s_idx);
    1903                 :          0 :         pa_strbuf_printf(buf, "reference = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->reference_volume));
    1904                 :          0 :         pa_strbuf_printf(buf, "real = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->real_volume));
    1905                 :          0 :         pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->soft_volume));
    1906                 :          0 :         pa_strbuf_printf(buf, "current_hw = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->thread_info.current_hw_volume));
    1907                 :          0 :         pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(so->save_volume));
    1908                 :            : 
    1909         [ #  # ]:          0 :         PA_IDXSET_FOREACH(o, so->outputs, i_idx) {
    1910                 :          0 :             pa_strbuf_printf(buf, "\tOutput %d: ", i_idx);
    1911                 :          0 :             pa_strbuf_printf(buf, "volume = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume));
    1912                 :          0 :             pa_strbuf_printf(buf, "reference_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->reference_ratio));
    1913                 :          0 :             pa_strbuf_printf(buf, "real_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->real_ratio));
    1914                 :          0 :             pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->soft_volume));
    1915                 :          0 :             pa_strbuf_printf(buf, "volume_factor = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume_factor));
    1916                 :          0 :             pa_strbuf_printf(buf, "volume_factor_source = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume_factor_source));
    1917                 :          0 :             pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(o->save_volume));
    1918                 :            :         }
    1919                 :            :     }
    1920                 :            : 
    1921                 :          0 :     return 0;
    1922                 :            : }
    1923                 :            : 
    1924                 :          0 : int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail, int *ifstate) {
    1925                 :            :     const char *cs;
    1926                 :            : 
    1927         [ #  # ]:          0 :     pa_assert(c);
    1928         [ #  # ]:          0 :     pa_assert(s);
    1929         [ #  # ]:          0 :     pa_assert(buf);
    1930                 :            : 
    1931                 :          0 :     cs = s+strspn(s, whitespace);
    1932                 :            : 
    1933         [ #  # ]:          0 :     if (*cs == '#' || !*cs)
    1934                 :            :         return 0;
    1935         [ #  # ]:          0 :     else if (*cs == '.') {
    1936         [ #  # ]:          0 :         if (!strcmp(cs, META_ELSE)) {
    1937 [ #  # ][ #  # ]:          0 :             if (!ifstate || *ifstate == IFSTATE_NONE) {
    1938                 :          0 :                 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
    1939                 :          0 :                 return -1;
    1940         [ #  # ]:          0 :             } else if (*ifstate == IFSTATE_TRUE)
    1941                 :          0 :                 *ifstate = IFSTATE_FALSE;
    1942                 :            :             else
    1943                 :          0 :                 *ifstate = IFSTATE_TRUE;
    1944                 :            :             return 0;
    1945         [ #  # ]:          0 :         } else if (!strcmp(cs, META_ENDIF)) {
    1946 [ #  # ][ #  # ]:          0 :             if (!ifstate || *ifstate == IFSTATE_NONE) {
    1947                 :          0 :                 pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
    1948                 :          0 :                 return -1;
    1949                 :            :             } else
    1950                 :          0 :                 *ifstate = IFSTATE_NONE;
    1951                 :          0 :             return 0;
    1952                 :            :         }
    1953 [ #  # ][ #  # ]:          0 :         if (ifstate && *ifstate == IFSTATE_FALSE)
    1954                 :            :             return 0;
    1955         [ #  # ]:          0 :         if (!strcmp(cs, META_FAIL))
    1956                 :          0 :             *fail = TRUE;
    1957         [ #  # ]:          0 :         else if (!strcmp(cs, META_NOFAIL))
    1958                 :          0 :             *fail = FALSE;
    1959                 :            :         else {
    1960                 :            :             size_t l;
    1961                 :          0 :             l = strcspn(cs, whitespace);
    1962                 :            : 
    1963 [ #  # ][ #  # ]:          0 :             if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) {
         [ #  # ][ #  # ]
    1964                 :            :                 struct stat st;
    1965                 :          0 :                 const char *filename = cs+l+strspn(cs+l, whitespace);
    1966                 :            : 
    1967         [ #  # ]:          0 :                 if (stat(filename, &st) < 0) {
    1968                 :          0 :                     pa_log_warn("stat('%s'): %s", filename, pa_cstrerror(errno));
    1969         [ #  # ]:          0 :                     if (*fail)
    1970                 :            :                         return -1;
    1971                 :            :                 } else {
    1972         [ #  # ]:          0 :                     if (S_ISDIR(st.st_mode)) {
    1973                 :            :                         DIR *d;
    1974                 :            : 
    1975         [ #  # ]:          0 :                         if (!(d = opendir(filename))) {
    1976                 :          0 :                             pa_log_warn("Failed to read '%s': %s", filename, pa_cstrerror(errno));
    1977         [ #  # ]:          0 :                             if (*fail)
    1978                 :            :                                 return -1;
    1979                 :            :                         } else {
    1980                 :            :                             unsigned i, count;
    1981                 :            :                             char **sorted_files;
    1982                 :            :                             struct dirent *de;
    1983                 :          0 :                             pa_bool_t failed = FALSE;
    1984                 :          0 :                             pa_dynarray *files = pa_dynarray_new();
    1985                 :            : 
    1986         [ #  # ]:          0 :                             while ((de = readdir(d))) {
    1987                 :            :                                 char *extn;
    1988                 :          0 :                                 size_t flen = strlen(de->d_name);
    1989                 :            : 
    1990         [ #  # ]:          0 :                                 if (flen < 4)
    1991                 :          0 :                                     continue;
    1992                 :            : 
    1993                 :          0 :                                 extn = &de->d_name[flen-3];
    1994         [ #  # ]:          0 :                                 if (strncmp(extn, ".pa", 3) == 0)
    1995                 :          0 :                                     pa_dynarray_append(files, pa_sprintf_malloc("%s" PA_PATH_SEP "%s", filename, de->d_name));
    1996                 :            :                             }
    1997                 :            : 
    1998                 :          0 :                             closedir(d);
    1999                 :            : 
    2000                 :          0 :                             count = pa_dynarray_size(files);
    2001                 :          0 :                             sorted_files = pa_xnew(char*, count);
    2002         [ #  # ]:          0 :                             for (i = 0; i < count; ++i)
    2003                 :          0 :                                 sorted_files[i] = pa_dynarray_get(files, i);
    2004                 :          0 :                             pa_dynarray_free(files, NULL);
    2005                 :            : 
    2006         [ #  # ]:          0 :                             for (i = 0; i < count; ++i) {
    2007         [ #  # ]:          0 :                                 for (unsigned j = 0; j < count; ++j) {
    2008         [ #  # ]:          0 :                                     if (strcmp(sorted_files[i], sorted_files[j]) < 0) {
    2009                 :          0 :                                         char *tmp = sorted_files[i];
    2010                 :          0 :                                         sorted_files[i] = sorted_files[j];
    2011                 :          0 :                                         sorted_files[j] = tmp;
    2012                 :            :                                     }
    2013                 :            :                                 }
    2014                 :            :                             }
    2015                 :            : 
    2016         [ #  # ]:          0 :                             for (i = 0; i < count; ++i) {
    2017         [ #  # ]:          0 :                                 if (!failed) {
    2018 [ #  # ][ #  # ]:          0 :                                     if (pa_cli_command_execute_file(c, sorted_files[i], buf, fail) < 0 && *fail)
    2019                 :          0 :                                         failed = TRUE;
    2020                 :            :                                 }
    2021                 :            : 
    2022                 :          0 :                                 pa_xfree(sorted_files[i]);
    2023                 :            :                             }
    2024                 :          0 :                             pa_xfree(sorted_files);
    2025         [ #  # ]:          0 :                             if (failed)
    2026                 :            :                                 return -1;
    2027                 :            :                         }
    2028 [ #  # ][ #  # ]:          0 :                     } else if (pa_cli_command_execute_file(c, filename, buf, fail) < 0 && *fail) {
    2029                 :            :                         return -1;
    2030                 :            :                     }
    2031                 :            :                 }
    2032 [ #  # ][ #  # ]:          0 :             } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) {
         [ #  # ][ #  # ]
    2033         [ #  # ]:          0 :                 if (!ifstate) {
    2034                 :          0 :                     pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
    2035                 :          0 :                     return -1;
    2036         [ #  # ]:          0 :                 } else if (*ifstate != IFSTATE_NONE) {
    2037                 :          0 :                     pa_strbuf_printf(buf, "Nested %s commands not supported\n", cs);
    2038                 :          0 :                     return -1;
    2039                 :            :                 } else {
    2040                 :          0 :                     const char *filename = cs+l+strspn(cs+l, whitespace);
    2041                 :            : 
    2042                 :            :                     /* Search DL_SEARCH_PATH unless the filename is absolute */
    2043         [ #  # ]:          0 :                     if (filename[0] == PA_PATH_SEP_CHAR) {
    2044                 :            : 
    2045                 :          0 :                         *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
    2046         [ #  # ]:          0 :                         pa_log_debug("Checking for existence of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure");
    2047                 :            : 
    2048                 :            :                     } else {
    2049                 :          0 :                         const char *paths, *state = NULL;
    2050                 :            :                         char *p;
    2051                 :            : 
    2052         [ #  # ]:          0 :                         if (!(paths = lt_dlgetsearchpath()))
    2053                 :            :                             return -1;
    2054                 :            : 
    2055         [ #  # ]:          0 :                         while ((p = pa_split(paths, ":", &state))) {
    2056                 :            :                             char *pathname;
    2057                 :            : 
    2058                 :          0 :                             pathname = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", p, filename);
    2059                 :          0 :                             pa_xfree(p);
    2060                 :            : 
    2061                 :          0 :                             *ifstate = access(pathname, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
    2062         [ #  # ]:          0 :                             pa_log_debug("Checking for existence of '%s': %s", pathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
    2063                 :            : 
    2064                 :          0 :                             pa_xfree(pathname);
    2065                 :            : 
    2066         [ #  # ]:          0 :                             if (*ifstate == IFSTATE_TRUE)
    2067                 :            :                                 break;
    2068                 :            :                         }
    2069                 :            :                     }
    2070                 :            : 
    2071                 :            :                 }
    2072                 :            :             } else {
    2073                 :          0 :                 pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs);
    2074         [ #  # ]:          0 :                 if (*fail) return -1;
    2075                 :            :             }
    2076                 :            :         }
    2077                 :            :     } else {
    2078                 :            :         const struct command*command;
    2079                 :          0 :         int unknown = 1;
    2080                 :            :         size_t l;
    2081                 :            : 
    2082 [ #  # ][ #  # ]:          0 :         if (ifstate && *ifstate == IFSTATE_FALSE)
    2083                 :            :             return 0;
    2084                 :            : 
    2085                 :          0 :         l = strcspn(cs, whitespace);
    2086                 :            : 
    2087         [ #  # ]:          0 :         for (command = commands; command->name; command++)
    2088 [ #  # ][ #  # ]:          0 :             if (strlen(command->name) == l && !strncmp(cs, command->name, l)) {
    2089                 :            :                 int ret;
    2090                 :          0 :                 pa_tokenizer *t = pa_tokenizer_new(cs, command->args);
    2091         [ #  # ]:          0 :                 pa_assert(t);
    2092                 :          0 :                 ret = command->proc(c, t, buf, fail);
    2093                 :          0 :                 pa_tokenizer_free(t);
    2094                 :          0 :                 unknown = 0;
    2095                 :            : 
    2096 [ #  # ][ #  # ]:          0 :                 if (ret < 0 && *fail)
    2097                 :            :                     return -1;
    2098                 :            : 
    2099                 :            :                 break;
    2100                 :            :             }
    2101                 :            : 
    2102         [ #  # ]:          0 :         if (unknown) {
    2103                 :          0 :             pa_strbuf_printf(buf, "Unknown command: %s\n", cs);
    2104         [ #  # ]:          0 :             if (*fail)
    2105                 :            :                 return -1;
    2106                 :            :         }
    2107                 :            :     }
    2108                 :            : 
    2109                 :          0 :     return 0;
    2110                 :            : }
    2111                 :            : 
    2112                 :          0 : int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
    2113                 :          0 :     return pa_cli_command_execute_line_stateful(c, s, buf, fail, NULL);
    2114                 :            : }
    2115                 :            : 
    2116                 :          0 : int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) {
    2117                 :            :     char line[2048];
    2118                 :          0 :     int ifstate = IFSTATE_NONE;
    2119                 :          0 :     int ret = -1;
    2120                 :          0 :     pa_bool_t _fail = TRUE;
    2121                 :            : 
    2122         [ #  # ]:          0 :     pa_assert(c);
    2123         [ #  # ]:          0 :     pa_assert(f);
    2124         [ #  # ]:          0 :     pa_assert(buf);
    2125                 :            : 
    2126         [ #  # ]:          0 :     if (!fail)
    2127                 :          0 :         fail = &_fail;
    2128                 :            : 
    2129         [ #  # ]:          0 :     while (fgets(line, sizeof(line), f)) {
    2130                 :          0 :         pa_strip_nl(line);
    2131                 :            : 
    2132 [ #  # ][ #  # ]:          0 :         if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail)
    2133                 :            :             goto fail;
    2134                 :            :     }
    2135                 :            : 
    2136                 :            :     ret = 0;
    2137                 :            : 
    2138                 :            : fail:
    2139                 :            : 
    2140                 :          0 :     return ret;
    2141                 :            : }
    2142                 :            : 
    2143                 :          0 : int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_bool_t *fail) {
    2144                 :          0 :     FILE *f = NULL;
    2145                 :          0 :     int ret = -1;
    2146                 :          0 :     pa_bool_t _fail = TRUE;
    2147                 :            : 
    2148         [ #  # ]:          0 :     pa_assert(c);
    2149         [ #  # ]:          0 :     pa_assert(fn);
    2150         [ #  # ]:          0 :     pa_assert(buf);
    2151                 :            : 
    2152         [ #  # ]:          0 :     if (!fail)
    2153                 :          0 :         fail = &_fail;
    2154                 :            : 
    2155         [ #  # ]:          0 :     if (!(f = pa_fopen_cloexec(fn, "r"))) {
    2156                 :          0 :         pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
    2157         [ #  # ]:          0 :         if (!*fail)
    2158                 :          0 :             ret = 0;
    2159                 :            :         goto fail;
    2160                 :            :     }
    2161                 :            : 
    2162                 :          0 :     pa_log_debug("Parsing script '%s'", fn);
    2163                 :          0 :     ret = pa_cli_command_execute_file_stream(c, f, buf, fail);
    2164                 :            : 
    2165                 :            : fail:
    2166         [ #  # ]:          0 :     if (f)
    2167                 :          0 :         fclose(f);
    2168                 :            : 
    2169                 :          0 :     return ret;
    2170                 :            : }
    2171                 :            : 
    2172                 :          0 : int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {
    2173                 :            :     const char *p;
    2174                 :          0 :     int ifstate = IFSTATE_NONE;
    2175                 :          0 :     pa_bool_t _fail = TRUE;
    2176                 :            : 
    2177         [ #  # ]:          0 :     pa_assert(c);
    2178         [ #  # ]:          0 :     pa_assert(s);
    2179         [ #  # ]:          0 :     pa_assert(buf);
    2180                 :            : 
    2181         [ #  # ]:          0 :     if (!fail)
    2182                 :          0 :         fail = &_fail;
    2183                 :            : 
    2184                 :          0 :     p = s;
    2185         [ #  # ]:          0 :     while (*p) {
    2186                 :          0 :         size_t l = strcspn(p, linebreak);
    2187                 :          0 :         char *line = pa_xstrndup(p, l);
    2188                 :            : 
    2189 [ #  # ][ #  # ]:          0 :         if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail) {
    2190                 :          0 :             pa_xfree(line);
    2191                 :          0 :             return -1;
    2192                 :            :         }
    2193                 :          0 :         pa_xfree(line);
    2194                 :            : 
    2195                 :          0 :         p += l;
    2196                 :          0 :         p += strspn(p, linebreak);
    2197                 :            :     }
    2198                 :            : 
    2199                 :            :     return 0;
    2200                 :            : }

Generated by: LCOV version 1.9