diff --git a/envy24control/envy24control.c b/envy24control/envy24control.c index 0b2749e..e5d89d0 100644 --- a/envy24control/envy24control.c +++ b/envy24control/envy24control.c @@ -2084,3 +2166,3 @@ int main(int argc, char **argv) view_spdif_playback = 0; profiles_file_name = DEFAULT_PROFILERC; default_profile = NULL; while ((c = getopt_long(argc, argv, "D:c:f:i:m:Mo:p:s:w:vt:", long_options, NULL)) != -1) { switch (c) { case 'D': - name = optarg; - card_number = atoi(strchr(name, ':') + sizeof(char)); - if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", card_number); - exit(1); + /* NPM: old code assumed ':' present, e.g. "-Dhw:66", + * (w/ .asoundrc "ctl.66 {type hw, card M66}") and would + * coredump if given "-D66". Prevent the coredump and even + * handle latter case even if keying off ':' is not a + * good way to do this. Note that for snd_card_get_index() + * "The accepted format is an integer value in ASCII representation or the card + * identifier (the id parameter for sound-card drivers). The control device + * name like /dev/snd/controlC0 is accepted, too." */ + if (!index(optarg, ':')) { + /* NPM: unlike old envy24control code, but behaving like amixer et al, + "-D66" is valid. Handle it. */ + snd_mixer_t *mixer; + struct snd_mixer_selem_regopt selem_regopt = { + .ver = 1, + .abstract = SND_MIXER_SABSTRACT_NONE, + .device = optarg, + }; + if ((err = snd_mixer_open(&mixer, 0)) < 0) { + fprintf(stderr, "envy24control: cannot open mixer: %s - '%s'\n", snd_strerror(err), optarg); + exit(1); + } + if ((err = snd_mixer_selem_register(mixer, &selem_regopt, NULL)) < 0) { + fprintf(stderr, "envy24control: cannot open mixer: %s - '%s'\n", snd_strerror(err), optarg); + exit(1); + } + name = optarg; /* NPM: now that device name validated, e.g. pass "-D66" unaltered to snd_ctl_open()... */ + } + else { + /* NPM: handle e.g. optarg == "hw:M66" */ + card_number = snd_card_get_index(strchr(optarg, ':') + sizeof(char)); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ + if (card_number < 0) { + fprintf(stderr, "envy24control: invalid ALSA audio device, invalid index or name for card: %s\n", optarg); + exit(1); + } + name = optarg; /* e.g. optarg == "hw:M66" passed to snd_ctl_open() below */ } break; case 'c': - i = atoi(optarg); - if (i < 0 || i >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", i); + card_number = snd_card_get_index(optarg); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ + if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */ + fprintf(stderr, "envy24control: invalid ALSA index or name for audio card: %s\n", optarg); exit(1); } - card_number = i; - sprintf(tmpname, "hw:%d", i); + sprintf(tmpname, "hw:%d", card_number); /* e.g. "hw:M66" for arg "-cM66" passed to snd_ctl_open() below */ name = tmpname; break; case 'f':