~cldunlap1/ubuntu/oneiric/alsa-utils/fix-for-816388

« back to all changes in this revision

Viewing changes to alsactl/init_parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2010-02-03 01:19:33 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100203011933-xl5mh2yyc4gfkp9h
Tags: 1.0.22-0ubuntu1
* New upstream release
* debian/patches/:
  - alsactl_brace.patch:
  - show_avail_formats.patch:
  - dont_free_if_init_file_doesnt_exist.patch: Applied upstream.
  + backport-fixes-head.patch: (c2eaf8, 0034b1, cdc496)

Show diffs side-by-side

added added

removed removed

Lines of Context:
485
485
        return -EINVAL;
486
486
}
487
487
 
 
488
static int do_match(const char *key, enum key_op op,
 
489
                    const char *key_value, const char *value)
 
490
{
 
491
        int match;
 
492
 
 
493
        if (value == NULL)
 
494
                return 0;
 
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);
 
499
                return 1;
 
500
        }
 
501
        if (!match && op == KEY_OP_NOMATCH) {
 
502
                dbg("%s is true (non-matching value)", key);
 
503
                return 1;
 
504
        }
 
505
        dbg("%s is false", key);
 
506
        return 0;
 
507
}
 
508
 
 
509
static int ctl_match(snd_ctl_elem_id_t *pattern, snd_ctl_elem_id_t *id)
 
510
{
 
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))
 
513
                return 0;
 
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))
 
516
                return 0;
 
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))
 
519
                return 0;
 
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))
 
522
                return 0;
 
523
        if (fnmatch(snd_ctl_elem_id_get_name(pattern), snd_ctl_elem_id_get_name(id), 0) != 0)
 
524
                return 0;
 
525
        return 1;
 
526
}
 
527
 
488
528
static const char *elemid_get(struct space *space, const char *attr)
489
529
{
490
530
        long long val;
649
689
                }
650
690
                return res;
651
691
        }
 
692
        if (strncasecmp(attr, "do_search", 9) == 0) {
 
693
                int err, index = 0;
 
694
                snd_hctl_elem_t *elem;
 
695
                snd_ctl_elem_id_t *id;
 
696
                char *pos = strchr(attr, ' ');
 
697
                if (pos)
 
698
                        index = strtol(pos, NULL, 0);
 
699
                err = snd_ctl_elem_id_malloc(&id);
 
700
                if (err < 0)
 
701
                        return NULL;
 
702
                elem = snd_hctl_first_elem(space->ctl_handle);
 
703
                while (elem) {
 
704
                        snd_hctl_elem_get_id(elem, id);
 
705
                        if (!ctl_match(space->ctl_id, id))
 
706
                                goto next_search;
 
707
                        if (index > 0) {
 
708
                                index--;
 
709
                                goto next_search;
 
710
                        }
 
711
                        strcpy(res, "1");
 
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");
 
715
                        return res;
 
716
                      next_search:
 
717
                        elem = snd_hctl_elem_next(elem);
 
718
                }
 
719
                snd_ctl_elem_id_free(id);
 
720
                strcpy(res, "0");
 
721
                return res;
 
722
        }
 
723
        if (strncasecmp(attr, "do_count", 8) == 0) {
 
724
                int err, index = 0;
 
725
                snd_hctl_elem_t *elem;
 
726
                snd_ctl_elem_id_t *id;
 
727
                err = snd_ctl_elem_id_malloc(&id);
 
728
                if (err < 0)
 
729
                        return NULL;
 
730
                elem = snd_hctl_first_elem(space->ctl_handle);
 
731
                while (elem) {
 
732
                        snd_hctl_elem_get_id(elem, id);
 
733
                        if (ctl_match(space->ctl_id, id))
 
734
                                index++;
 
735
                        elem = snd_hctl_elem_next(elem);
 
736
                }
 
737
                snd_ctl_elem_id_free(id);
 
738
                sprintf(res, "%u", index);
 
739
                dbg("do_ctl_count found %s controls", res);
 
740
                return res;
 
741
        }
652
742
        Perror(space, "unknown ctl{} attribute '%s'", attr);
653
743
        return NULL;
654
744
  value:
1150
1240
        *tail = 0;
1151
1241
}
1152
1242
 
1153
 
static int do_match(const char *key, enum key_op op,
1154
 
                    const char *key_value, const char *value)
1155
 
{
1156
 
        int match;
1157
 
 
1158
 
        if (value == NULL)
1159
 
                return 0;
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);
1164
 
                return 1;
1165
 
        }
1166
 
        if (!match && op == KEY_OP_NOMATCH) {
1167
 
                dbg("%s is true (non-matching value)", key);
1168
 
                return 1;
1169
 
        }
1170
 
        dbg("%s is false", key);
1171
 
        return 0;
1172
 
}
1173
 
 
1174
 
static int ctl_match(snd_ctl_elem_id_t *pattern, snd_ctl_elem_id_t *id)
1175
 
{
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))
1178
 
                return 0;
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))
1181
 
                return 0;
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))
1184
 
                return 0;
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))
1187
 
                return 0;
1188
 
        if (fnmatch(snd_ctl_elem_id_get_name(pattern), snd_ctl_elem_id_get_name(id), 0) != 0)
1189
 
                return 0;
1190
 
        return 1;
1191
 
}
1192
 
 
1193
1243
static
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)
1197
1247
{
1198
 
        char *pos = strchr(command0, ' ');
1199
 
        int cmdlen = pos ? pos - command0 : strlen(command0);
1200
 
        int err, index;
1201
 
        snd_hctl_elem_t *elem;
1202
 
        snd_ctl_elem_id_t *id;
1203
 
        
1204
 
        if (cmdlen == 12 && strncmp(command0, "__ctl_search", 12) == 0) {
1205
 
                index = 0;
1206
 
                if (pos)
1207
 
                        index = strtol(pos, NULL, 0);
1208
 
                err = snd_ctl_elem_id_malloc(&id);
1209
 
                if (err < 0)
1210
 
                        return EXIT_FAILURE;
1211
 
                elem = snd_hctl_first_elem(space->ctl_handle);
1212
 
                while (elem) {
1213
 
                        snd_hctl_elem_get_id(elem, id);
1214
 
                        if (!ctl_match(space->ctl_id, id))
1215
 
                                goto next_search;
1216
 
                        if (index > 0) {
1217
 
                                index--;
1218
 
                                goto next_search;
1219
 
                        }
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;
1225
 
                      next_search:
1226
 
                        elem = snd_hctl_elem_next(elem);
1227
 
                }
1228
 
                snd_ctl_elem_id_free(id);
1229
 
                return EXIT_FAILURE;
1230
 
        }
1231
 
        if (cmdlen == 11 && strncmp(command0, "__ctl_count", 11) == 0) {
1232
 
                index = 0;
1233
 
                err = snd_ctl_elem_id_malloc(&id);
1234
 
                if (err < 0)
1235
 
                        return EXIT_FAILURE;
1236
 
                elem = snd_hctl_first_elem(space->ctl_handle);
1237
 
                while (elem) {
1238
 
                        snd_hctl_elem_get_id(elem, id);
1239
 
                        if (!ctl_match(space->ctl_id, id))
1240
 
                                goto next_count;
1241
 
                        index++;
1242
 
                      next_count:
1243
 
                        elem = snd_hctl_elem_next(elem);
1244
 
                }
1245
 
                snd_ctl_elem_id_free(id);
1246
 
                if (index > 0) {
1247
 
                        snprintf(result, ressize, "%u", index);
1248
 
                        dbg("__ctl_count found %s controls", result);
1249
 
                        return EXIT_SUCCESS;
1250
 
                }
1251
 
                dbg("__ctl_count no match");
1252
 
                return EXIT_FAILURE;
1253
 
        }
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;
 
1253
        }
 
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;
1255
1260
        }
1256
1261
        Perror(space, "unknown buildin command '%s'", command0);
1257
1262
        return EXIT_FAILURE;
1329
1334
                                if (space->program_result == NULL)
1330
1335
                                        break;
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))
1335
 
                                        break;
 
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)
 
1343
                                                break;
 
1344
                                        if (err != 0 && op == KEY_OP_MATCH)
 
1345
                                                break;
 
1346
                                } else {
 
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))
 
1350
                                                break;
 
1351
                                }
1336
1352
                        } else {
1337
1353
                                Perror(space, "invalid CTL{} operation");
1338
1354
                                goto invalid;
1731
1747
                        }
1732
1748
                        first = 0;
1733
1749
                        err = init_space(&space, card);
1734
 
                        if (err == 0 &&
1735
 
                            (space->rootdir = new_root_dir(filename)) != NULL)
1736
 
                                err = parse(space, filename);
1737
 
                        free_space(space);
 
1750
                        if (err == 0) {
 
1751
                                space->rootdir = new_root_dir(filename);
 
1752
                                if (space->rootdir != NULL)
 
1753
                                        err = parse(space, filename);
 
1754
                                free_space(space);
 
1755
                        }
1738
1756
                        if (err < 0)
1739
1757
                                break;
1740
1758
                }
1746
1764
                }
1747
1765
                memset(&space, 0, sizeof(space));
1748
1766
                err = init_space(&space, card);
1749
 
                if (err == 0 &&
1750
 
                    (space->rootdir = new_root_dir(filename)) != NULL)
1751
 
                        err = parse(space, filename);
1752
 
                free_space(space);
 
1767
                if (err == 0) {
 
1768
                        space->rootdir = new_root_dir(filename);
 
1769
                        if (space->rootdir  != NULL)
 
1770
                                err = parse(space, filename);
 
1771
                        free_space(space);
 
1772
                }
1753
1773
        }
1754
1774
  error:
1755
1775
        sysfs_cleanup();