diff options
author | Jaroslav Kysela <perex@perex.cz> | 2021-05-14 12:20:18 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2021-05-17 16:49:46 +0200 |
commit | 5e7c507152f71ea1323c6583849528b370441cfc (patch) | |
tree | e954acca5458f114d18947e904ca10881b435a81 | |
parent | f821f097271b9b31a706e606dca33e7dca51ad5c (diff) | |
download | alsa-lib-5e7c507152f71ea1323c6583849528b370441cfc.tar.gz |
ucm: add cfg-save command
Allow to save whole (or partial) local UCM alsa library configuration
to a file.
Syntax (saves key1.key2 sub-tree):
Sequence [
cfg-save "/tmp/my-file.conf:key1.key2"
]
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | src/ucm/main.c | 41 | ||||
-rw-r--r-- | src/ucm/parser.c | 10 | ||||
-rw-r--r-- | src/ucm/ucm_local.h | 2 | ||||
-rw-r--r-- | src/ucm/utils.c | 3 |
4 files changed, 56 insertions, 0 deletions
diff --git a/src/ucm/main.c b/src/ucm/main.c index f50ccff5..b1536ac3 100644 --- a/src/ucm/main.c +++ b/src/ucm/main.c @@ -573,6 +573,42 @@ static int execute_sysw(const char *sysw) return 0; } +static int execute_cfgsave(snd_use_case_mgr_t *uc_mgr, const char *filename) +{ + snd_config_t *config = uc_mgr->local_config; + char *file, *root; + snd_output_t *out; + int err = 0; + + file = strdup(filename); + if (!file) + return -ENOMEM; + root = strchr(file, ':'); + if (root) { + *root = '\0'; + err = snd_config_search(config, root + 1, &config); + if (err < 0) { + uc_error("Unable to find subtree '%s'", root); + goto _err; + } + } + + err = snd_output_stdio_open(&out, file, "w+"); + if (err < 0) { + uc_error("unable to open file '%s': %s", file, snd_strerror(err)); + goto _err; + } + err = snd_config_save(config, out); + snd_output_close(out); + if (err < 0) { + uc_error("unable to save configuration: %s", snd_strerror(err)); + goto _err; + } +_err: + free(file); + return err; +} + static int rewrite_device_value(snd_use_case_mgr_t *uc_mgr, const char *name, char **value) { char *sval; @@ -754,6 +790,11 @@ shell_retry: if (err < 0) goto __fail; break; + case SEQUENCE_ELEMENT_TYPE_CFGSAVE: + err = execute_cfgsave(uc_mgr, s->data.cfgsave); + if (err < 0) + goto __fail; + break; default: uc_error("unknown sequence command %i", s->type); break; diff --git a/src/ucm/parser.c b/src/ucm/parser.c index 2a425da6..68b0ee62 100644 --- a/src/ucm/parser.c +++ b/src/ucm/parser.c @@ -924,6 +924,16 @@ exec: goto exec; } + if (strcmp(cmd, "cfg-save") == 0) { + curr->type = SEQUENCE_ELEMENT_TYPE_CFGSAVE; + err = parse_string_substitute3(uc_mgr, n, &curr->data.cfgsave); + if (err < 0) { + uc_error("error: sysw requires a string!"); + return err; + } + continue; + } + if (strcmp(cmd, "comment") == 0) goto skip; diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h index c0374148..8eb1fc7a 100644 --- a/src/ucm/ucm_local.h +++ b/src/ucm/ucm_local.h @@ -56,6 +56,7 @@ #define SEQUENCE_ELEMENT_TYPE_CTL_REMOVE 9 #define SEQUENCE_ELEMENT_TYPE_CMPT_SEQ 10 #define SEQUENCE_ELEMENT_TYPE_SYSSET 11 +#define SEQUENCE_ELEMENT_TYPE_CFGSAVE 12 struct ucm_value { struct list_head list; @@ -78,6 +79,7 @@ struct sequence_element { char *cset; char *exec; char *sysw; + char *cfgsave; struct component_sequence cmpt_seq; /* component sequence */ } data; }; diff --git a/src/ucm/utils.c b/src/ucm/utils.c index 0eaf6c3c..f3a8c9ba 100644 --- a/src/ucm/utils.c +++ b/src/ucm/utils.c @@ -512,6 +512,9 @@ void uc_mgr_free_sequence_element(struct sequence_element *seq) case SEQUENCE_ELEMENT_TYPE_SHELL: free(seq->data.exec); break; + case SEQUENCE_ELEMENT_TYPE_CFGSAVE: + free(seq->data.cfgsave); + break; default: break; } |