]> git.alsa-project.org Git - alsa-lib.git/commitdiff
ucm: add cfg-save command
authorJaroslav Kysela <perex@perex.cz>
Fri, 14 May 2021 10:20:18 +0000 (12:20 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 17 May 2021 14:49:46 +0000 (16:49 +0200)
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>
src/ucm/main.c
src/ucm/parser.c
src/ucm/ucm_local.h
src/ucm/utils.c

index f50ccff5d30ba37617991eb3996a56a9bb3643e7..b1536ac350bb837be28cb06ccd5f12acec3e234e 100644 (file)
@@ -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;
index 2a425da6de87bc98bfb32fe6f88f15739427aa77..68b0ee6273776aceae74e9c6b5a9c7f4d6be0d61 100644 (file)
@@ -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;
 
index c03741486cfe7ba4524206b89b210d73dcb8f71f..8eb1fc7a2f4dd7fbc555e9fd628921793e4e2f64 100644 (file)
@@ -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;
 };
index 0eaf6c3cb84ac6fa5b557630b4cb61423a90dc0c..f3a8c9ba5264551f9d428a92276da6d7943cb875 100644 (file)
@@ -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;
        }