mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-09-19 17:49:59 +02:00
alsactl: add dump-cfg and dump-state commands
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
09c04f8935
commit
c1474594dc
8 changed files with 103 additions and 34 deletions
|
@ -41,6 +41,10 @@ control device.
|
||||||
|
|
||||||
\fIclean\fP clean the controls created by applications.
|
\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,
|
If no soundcards are specified, setup for all cards will be saved,
|
||||||
loaded or monitored.
|
loaded or monitored.
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
#ifndef SYS_ASOUNDRC
|
#ifndef SYS_ASOUNDRC
|
||||||
|
@ -111,6 +110,8 @@ static struct arg args[] = {
|
||||||
{ CARDCMD, "rdaemon", "like daemon but do the state restore at first" },
|
{ CARDCMD, "rdaemon", "like daemon but do the state restore at first" },
|
||||||
{ KILLCMD, "kill", "notify daemon to quit, rescan or save_and_quit" },
|
{ KILLCMD, "kill", "notify daemon to quit, rescan or save_and_quit" },
|
||||||
{ CARDCMD, "monitor", "monitor control events" },
|
{ 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 }
|
{ 0, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ static void help(void)
|
||||||
strcat(buf, "<card>");
|
strcat(buf, "<card>");
|
||||||
else if (sarg & KILLCMD)
|
else if (sarg & KILLCMD)
|
||||||
strcat(buf, "<cmd>");
|
strcat(buf, "<cmd>");
|
||||||
printf(" %-8s %-6s %s\n", larg ? larg : "",
|
printf(" %-10s %-6s %s\n", larg ? larg : "",
|
||||||
buf, a->comment);
|
buf, a->comment);
|
||||||
continue;
|
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)
|
#define NO_NICE (-100000)
|
||||||
|
|
||||||
static void do_nice(int use_nice, int sched_idle)
|
static void do_nice(int use_nice, int sched_idle)
|
||||||
|
@ -399,6 +442,10 @@ int main(int argc, char *argv[])
|
||||||
res = monitor(cardname);
|
res = monitor(cardname);
|
||||||
} else if (!strcmp(cmd, "clean")) {
|
} else if (!strcmp(cmd, "clean")) {
|
||||||
res = clean(cardname, extra_args);
|
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 {
|
} else {
|
||||||
fprintf(stderr, "alsactl: Unknown command '%s'...\n", cmd);
|
fprintf(stderr, "alsactl: Unknown command '%s'...\n", cmd);
|
||||||
res = -ENODEV;
|
res = -ENODEV;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
extern int debugflag;
|
extern int debugflag;
|
||||||
extern int force_restore;
|
extern int force_restore;
|
||||||
extern int ignore_nocards;
|
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_DISABLED (1<<0)
|
||||||
#define FLAG_UCM_DEFAULTS (1<<1)
|
#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(const char *file, int flags, const char *cardname);
|
||||||
int init_ucm(int flags, int cardno);
|
int init_ucm(int flags, int cardno);
|
||||||
int state_lock(const char *file, int timeout);
|
int state_lock(const char *file, int timeout);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
static int clean_one_control(snd_ctl_t *handle, snd_ctl_elem_id_t *elem_id,
|
static int clean_one_control(snd_ctl_t *handle, snd_ctl_elem_id_t *elem_id,
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
struct id_list {
|
struct id_list {
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "aconfig.h"
|
#include "aconfig.h"
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1648,38 +1647,17 @@ out:
|
||||||
int load_state(const char *file, const char *initfile, int initflags,
|
int load_state(const char *file, const char *initfile, int initflags,
|
||||||
const char *cardname, int do_init)
|
const char *cardname, int do_init)
|
||||||
{
|
{
|
||||||
int err, finalerr = 0;
|
int err, finalerr = 0, open_failed;
|
||||||
snd_config_t *config;
|
snd_config_t *config;
|
||||||
snd_input_t *in;
|
|
||||||
int stdio, lock_fd = -EINVAL;
|
|
||||||
|
|
||||||
err = snd_config_top(&config);
|
err = load_configuration(file, &config, &open_failed);
|
||||||
if (err < 0) {
|
if (err < 0 && !open_failed)
|
||||||
error("snd_config_top error: %s", snd_strerror(err));
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
stdio = !strcmp(file, "-");
|
if (open_failed) {
|
||||||
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 {
|
|
||||||
int card, first = 1;
|
int card, first = 1;
|
||||||
char cardname1[16];
|
char cardname1[16];
|
||||||
|
|
||||||
if (lock_fd >= 0)
|
|
||||||
state_unlock(lock_fd, file);
|
|
||||||
error("Cannot open %s for reading: %s", file, snd_strerror(err));
|
error("Cannot open %s for reading: %s", file, snd_strerror(err));
|
||||||
finalerr = err;
|
finalerr = err;
|
||||||
if (cardname) {
|
if (cardname) {
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "alsactl.h"
|
#include "alsactl.h"
|
||||||
|
|
||||||
int file_map(const char *filename, char **buf, size_t *bufsize)
|
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,
|
fprintf(stderr, "alsa-lib %s:%i:(%s) %s%s%s\n", file, line, function,
|
||||||
buf, err ? ": " : "", err ? snd_strerror(err) : "");
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue