488
static int do_match(const char *key, enum key_op op,
489
const char *key_value, const char *value)
495
dbg("match %s '%s' <-> '%s'", key, key_value, value);
496
match = fnmatch(key_value, value, 0) == 0;
497
if (match && op == KEY_OP_MATCH) {
498
dbg("%s is true (matching value)", key);
501
if (!match && op == KEY_OP_NOMATCH) {
502
dbg("%s is true (non-matching value)", key);
505
dbg("%s is false", key);
509
static int ctl_match(snd_ctl_elem_id_t *pattern, snd_ctl_elem_id_t *id)
511
if (snd_ctl_elem_id_get_interface(pattern) != -1 &&
512
snd_ctl_elem_id_get_interface(pattern) != snd_ctl_elem_id_get_interface(id))
514
if (snd_ctl_elem_id_get_device(pattern) != -1 &&
515
snd_ctl_elem_id_get_device(pattern) != snd_ctl_elem_id_get_device(id))
517
if (snd_ctl_elem_id_get_subdevice(pattern) != -1 &&
518
snd_ctl_elem_id_get_subdevice(pattern) != snd_ctl_elem_id_get_subdevice(id))
520
if (snd_ctl_elem_id_get_index(pattern) != -1 &&
521
snd_ctl_elem_id_get_index(pattern) != snd_ctl_elem_id_get_index(id))
523
if (fnmatch(snd_ctl_elem_id_get_name(pattern), snd_ctl_elem_id_get_name(id), 0) != 0)
488
528
static const char *elemid_get(struct space *space, const char *attr)
692
if (strncasecmp(attr, "do_search", 9) == 0) {
694
snd_hctl_elem_t *elem;
695
snd_ctl_elem_id_t *id;
696
char *pos = strchr(attr, ' ');
698
index = strtol(pos, NULL, 0);
699
err = snd_ctl_elem_id_malloc(&id);
702
elem = snd_hctl_first_elem(space->ctl_handle);
704
snd_hctl_elem_get_id(elem, id);
705
if (!ctl_match(space->ctl_id, id))
712
snd_ctl_elem_id_copy(space->ctl_id, id);
713
snd_ctl_elem_id_free(id);
714
dbg("do_ctl_search found a control");
717
elem = snd_hctl_elem_next(elem);
719
snd_ctl_elem_id_free(id);
723
if (strncasecmp(attr, "do_count", 8) == 0) {
725
snd_hctl_elem_t *elem;
726
snd_ctl_elem_id_t *id;
727
err = snd_ctl_elem_id_malloc(&id);
730
elem = snd_hctl_first_elem(space->ctl_handle);
732
snd_hctl_elem_get_id(elem, id);
733
if (ctl_match(space->ctl_id, id))
735
elem = snd_hctl_elem_next(elem);
737
snd_ctl_elem_id_free(id);
738
sprintf(res, "%u", index);
739
dbg("do_ctl_count found %s controls", res);
652
742
Perror(space, "unknown ctl{} attribute '%s'", attr);
1153
static int do_match(const char *key, enum key_op op,
1154
const char *key_value, const char *value)
1160
dbg("match %s '%s' <-> '%s'", key, key_value, value);
1161
match = fnmatch(key_value, value, 0) == 0;
1162
if (match && op == KEY_OP_MATCH) {
1163
dbg("%s is true (matching value)", key);
1166
if (!match && op == KEY_OP_NOMATCH) {
1167
dbg("%s is true (non-matching value)", key);
1170
dbg("%s is false", key);
1174
static int ctl_match(snd_ctl_elem_id_t *pattern, snd_ctl_elem_id_t *id)
1176
if (snd_ctl_elem_id_get_interface(pattern) != -1 &&
1177
snd_ctl_elem_id_get_interface(pattern) != snd_ctl_elem_id_get_interface(id))
1179
if (snd_ctl_elem_id_get_device(pattern) != -1 &&
1180
snd_ctl_elem_id_get_device(pattern) != snd_ctl_elem_id_get_device(id))
1182
if (snd_ctl_elem_id_get_subdevice(pattern) != -1 &&
1183
snd_ctl_elem_id_get_subdevice(pattern) != snd_ctl_elem_id_get_subdevice(id))
1185
if (snd_ctl_elem_id_get_index(pattern) != -1 &&
1186
snd_ctl_elem_id_get_index(pattern) != snd_ctl_elem_id_get_index(id))
1188
if (fnmatch(snd_ctl_elem_id_get_name(pattern), snd_ctl_elem_id_get_name(id), 0) != 0)
1194
1244
int run_program1(struct space *space,
1195
1245
const char *command0, char *result,
1196
1246
size_t ressize, size_t *reslen, int log)
1198
char *pos = strchr(command0, ' ');
1199
int cmdlen = pos ? pos - command0 : strlen(command0);
1201
snd_hctl_elem_t *elem;
1202
snd_ctl_elem_id_t *id;
1204
if (cmdlen == 12 && strncmp(command0, "__ctl_search", 12) == 0) {
1207
index = strtol(pos, NULL, 0);
1208
err = snd_ctl_elem_id_malloc(&id);
1210
return EXIT_FAILURE;
1211
elem = snd_hctl_first_elem(space->ctl_handle);
1213
snd_hctl_elem_get_id(elem, id);
1214
if (!ctl_match(space->ctl_id, id))
1220
strlcpy(result, "0", ressize);
1221
snd_ctl_elem_id_copy(space->ctl_id, id);
1222
snd_ctl_elem_id_free(id);
1223
dbg("__ctl_search found a control");
1224
return EXIT_SUCCESS;
1226
elem = snd_hctl_elem_next(elem);
1228
snd_ctl_elem_id_free(id);
1229
return EXIT_FAILURE;
1231
if (cmdlen == 11 && strncmp(command0, "__ctl_count", 11) == 0) {
1233
err = snd_ctl_elem_id_malloc(&id);
1235
return EXIT_FAILURE;
1236
elem = snd_hctl_first_elem(space->ctl_handle);
1238
snd_hctl_elem_get_id(elem, id);
1239
if (!ctl_match(space->ctl_id, id))
1243
elem = snd_hctl_elem_next(elem);
1245
snd_ctl_elem_id_free(id);
1247
snprintf(result, ressize, "%u", index);
1248
dbg("__ctl_count found %s controls", result);
1249
return EXIT_SUCCESS;
1251
dbg("__ctl_count no match");
1252
return EXIT_FAILURE;
1254
if (cmdlen == 11 && strncmp(command0, "__ctl_write", 11) == 0) {
1248
if (strncmp(command0, "__ctl_search", 12) == 0) {
1249
const char *res = elemid_get(space, "do_search");
1250
if (res == NULL || strcmp(res, "1") != 0)
1251
return EXIT_FAILURE;
1252
return EXIT_SUCCESS;
1254
if (strncmp(command0, "__ctl_count", 11) == 0) {
1255
const char *res = elemid_get(space, "do_count");
1256
if (res == NULL || strcmp(res, "0") == 0)
1257
return EXIT_FAILURE;
1258
strlcpy(result, res, ressize);
1259
return EXIT_SUCCESS;
1256
1261
Perror(space, "unknown buildin command '%s'", command0);
1257
1262
return EXIT_FAILURE;
1329
1334
if (space->program_result == NULL)
1331
1336
} else if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {
1332
dbg("ctl match: '%s' '%s'", value, attr);
1333
temp = (char *)elemid_get(space, attr);
1334
if (!do_match(key, op, value, temp))
1337
if (strncmp(attr, "write", 5) == 0) {
1338
strlcpy(result, value, sizeof(result));
1339
apply_format(space, result, sizeof(result));
1340
dbg("ctl write: '%s' '%s'", value, attr);
1341
err = elemid_set(space, "values", result);
1342
if (err == 0 && op == KEY_OP_NOMATCH)
1344
if (err != 0 && op == KEY_OP_MATCH)
1347
temp = (char *)elemid_get(space, attr);
1348
dbg("ctl match: '%s' '%s' '%s'", attr, value, temp);
1349
if (!do_match(key, op, value, temp))
1337
1353
Perror(space, "invalid CTL{} operation");