]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsactl: add dump-cfg and dump-state commands
authorJaroslav Kysela <perex@perex.cz>
Sun, 7 Mar 2021 18:58:33 +0000 (19:58 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 7 Mar 2021 18:58:33 +0000 (19:58 +0100)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
alsactl/alsactl.1
alsactl/alsactl.c
alsactl/alsactl.h
alsactl/clean.c
alsactl/daemon.c
alsactl/init_parse.c
alsactl/state.c
alsactl/utils.c

index 1c9c9b9cbc21471b41a4b17f1683937338a4bd29..5452ef599556178db86fed0e201b62c81243ac7f 100644 (file)
@@ -41,6 +41,10 @@ control device.
 
 \fIclean\fP clean the controls created by applications.
 
+\fIdump-state\fP dump the current state (all cards).
+
+\fIdump-cfg\fP dump the current configuration (all cards, hooks are evaluated).
+
 If no soundcards are specified, setup for all cards will be saved,
 loaded or monitored.
 
index a3a6bfad49254e3b4f381ace54c1643d4bc76b2c..1d2ff3ed0a200d0207487b50bb8f00e46a5b6174 100644 (file)
@@ -29,7 +29,6 @@
 #include <errno.h>
 #include <syslog.h>
 #include <sched.h>
-#include <alsa/asoundlib.h>
 #include "alsactl.h"
 
 #ifndef SYS_ASOUNDRC
@@ -111,6 +110,8 @@ static struct arg args[] = {
 { CARDCMD, "rdaemon", "like daemon but do the state restore at first" },
 { KILLCMD, "kill", "notify daemon to quit, rescan or save_and_quit" },
 { CARDCMD, "monitor", "monitor control events" },
+{ EMPCMD, "dump-state", "dump the state (for all cards)" },
+{ EMPCMD, "dump-cfg", "dump the configuration (expanded, for all cards)" },
 { 0, NULL, NULL }
 };
 
@@ -139,7 +140,7 @@ static void help(void)
                                strcat(buf, "<card>");
                        else if (sarg & KILLCMD)
                                strcat(buf, "<cmd>");
-                       printf("  %-8s  %-6s  %s\n", larg ? larg : "",
+                       printf("  %-10s  %-6s  %s\n", larg ? larg : "",
                                                        buf, a->comment);
                        continue;
                }
@@ -154,6 +155,48 @@ static void help(void)
        }
 }
 
+static int dump_config_tree(snd_config_t *top)
+{
+       snd_output_t *out;
+       int err;
+
+       err = snd_output_stdio_attach(&out, stdout, 0);
+       if (err < 0)
+               return err;
+       err = snd_config_save(top, out);
+       snd_output_close(out);
+       return 0;
+}
+
+static int dump_state(const char *file)
+{
+       snd_config_t *top;
+       int err;
+
+       err = load_configuration(file, &top, NULL);
+       if (err < 0)
+               return err;
+       err = dump_config_tree(top);
+       snd_config_delete(top);
+       snd_config_update_free_global();
+       return err;
+}
+
+static int dump_configuration(void)
+{
+       snd_config_t *top, *cfg2;
+       int err;
+
+       err = snd_config_update_ref(&top);
+       if (err < 0)
+               return err;
+       /* expand cards.* tree */
+       snd_config_search_definition(top, "cards", "dummy", &cfg2);
+       err = dump_config_tree(top);
+       snd_config_unref(top);
+       return err;
+}
+
 #define NO_NICE (-100000)
 
 static void do_nice(int use_nice, int sched_idle)
@@ -399,6 +442,10 @@ int main(int argc, char *argv[])
                res = monitor(cardname);
        } else if (!strcmp(cmd, "clean")) {
                res = clean(cardname, extra_args);
+       } else if (!strcmp(cmd, "dump-state")) {
+               res = dump_state(cfgfile);
+       } else if (!strcmp(cmd, "dump-cfg")) {
+               res = dump_configuration();
        } else {
                fprintf(stderr, "alsactl: Unknown command '%s'...\n", cmd);
                res = -ENODEV;
index 74079ded1c73cf1e55597264ac907ab2dd13d52b..119e3b4b850efe9bf6ffa7c4af218d6e7dcb83cd 100644 (file)
@@ -1,3 +1,5 @@
+#include <alsa/asoundlib.h>
+
 extern int debugflag;
 extern int force_restore;
 extern int ignore_nocards;
@@ -28,6 +30,7 @@ void error_handler(const char *file, int line, const char *function, int err, co
 #define FLAG_UCM_DISABLED      (1<<0)
 #define FLAG_UCM_DEFAULTS      (1<<1)
 
+int load_configuration(const char *file, snd_config_t **top, int *open_failed);
 int init(const char *file, int flags, const char *cardname);
 int init_ucm(int flags, int cardno);
 int state_lock(const char *file, int timeout);
index b74714f2d909e74d31e80d534279b4f95ff88084..4808225a00e31da9130a6b1df11d50be2bdfc01b 100644 (file)
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <assert.h>
 #include <errno.h>
-#include <alsa/asoundlib.h>
 #include "alsactl.h"
 
 static int clean_one_control(snd_ctl_t *handle, snd_ctl_elem_id_t *elem_id,
index ee03991ef5f1224d9f1222ec6935a0d7914b9478..5109015d5b54086d776bd8f3dfcd5e8665ceb411 100644 (file)
@@ -29,7 +29,6 @@
 #include <signal.h>
 #include <time.h>
 #include <poll.h>
-#include <alsa/asoundlib.h>
 #include "alsactl.h"
 
 struct id_list {
index 7a6402a26e566ccb36becea92d0c73021fe32d7e..e7b352c2aad1c5ff202fc09ad1d07888bf1eb261 100644 (file)
@@ -37,7 +37,6 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <math.h>
-#include <alsa/asoundlib.h>
 #include "aconfig.h"
 #include "alsactl.h"
 #include "list.h"
index ea1d3bcaaddfe6dbf18d6726afe709add13eef05..71e5465f9be6f0dc49fc52452ae31545ab175db1 100644 (file)
@@ -27,7 +27,6 @@
 #include <stdio.h>
 #include <assert.h>
 #include <errno.h>
-#include <alsa/asoundlib.h>
 #include "alsactl.h"
 
 
@@ -1648,38 +1647,17 @@ out:
 int load_state(const char *file, const char *initfile, int initflags,
               const char *cardname, int do_init)
 {
-       int err, finalerr = 0;
+       int err, finalerr = 0, open_failed;
        snd_config_t *config;
-       snd_input_t *in;
-       int stdio, lock_fd = -EINVAL;
 
-       err = snd_config_top(&config);
-       if (err < 0) {
-               error("snd_config_top error: %s", snd_strerror(err));
+       err = load_configuration(file, &config, &open_failed);
+       if (err < 0 && !open_failed)
                return err;
-       }
-       stdio = !strcmp(file, "-");
-       if (stdio) {
-               err = snd_input_stdio_attach(&in, stdin, 0);
-       } else {
-               lock_fd = state_lock(file, 10);
-               err = lock_fd >= 0 ? snd_input_stdio_open(&in, file, "r") : lock_fd;
-       }
-       if (err >= 0) {
-               err = snd_config_load(config, in);
-               snd_input_close(in);
-               if (lock_fd >= 0)
-                       state_unlock(lock_fd, file);
-               if (err < 0) {
-                       error("snd_config_load error: %s", snd_strerror(err));
-                       goto out;
-               }
-       } else {
+
+       if (open_failed) {
                int card, first = 1;
                char cardname1[16];
 
-               if (lock_fd >= 0)
-                       state_unlock(lock_fd, file);
                error("Cannot open %s for reading: %s", file, snd_strerror(err));
                finalerr = err;
                if (cardname) {
index f67421def07ad1650841b6485ca8a0645e1b9a66..ede7319c3bdb1cc70dbd3ca374a1395ea0fed20e 100644 (file)
@@ -30,8 +30,6 @@
 #include <syslog.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
-
-#include <alsa/asoundlib.h>
 #include "alsactl.h"
 
 int file_map(const char *filename, char **buf, size_t *bufsize)
@@ -193,3 +191,45 @@ void error_handler(const char *file, int line, const char *function, int err, co
                fprintf(stderr, "alsa-lib %s:%i:(%s) %s%s%s\n", file, line, function,
                                buf, err ? ": " : "", err ? snd_strerror(err) : "");
 }
+
+int load_configuration(const char *file, snd_config_t **top, int *open_failed)
+{
+       snd_config_t *config;
+       snd_input_t *in;
+       int err, stdio_flag, lock_fd = -EINVAL;
+
+       *top = NULL;
+       if (open_failed)
+               *open_failed = 0;
+       err = snd_config_top(&config);
+       if (err < 0) {
+               error("snd_config_top error: %s", snd_strerror(err));
+               return err;
+       }
+       stdio_flag = !strcmp(file, "-");
+       if (stdio_flag) {
+               err = snd_input_stdio_attach(&in, stdin, 0);
+       } else {
+               lock_fd = state_lock(file, 10);
+               err = lock_fd >= 0 ? snd_input_stdio_open(&in, file, "r") : lock_fd;
+       }
+       if (err < 0) {
+               if (open_failed)
+                       *open_failed = 1;
+               goto out;
+       }
+       err = snd_config_load(config, in);
+       snd_input_close(in);
+       if (lock_fd >= 0)
+               state_unlock(lock_fd, file);
+       if (err < 0) {
+               error("snd_config_load error: %s", snd_strerror(err));
+out:
+               snd_config_delete(config);
+               snd_config_update_free_global();
+               return err;
+       } else {
+               *top = config;
+               return 0;
+       }
+}