alsactl: fix sysfsroot path and parser extensions

The sysfsroot path is /sys/class/sound/cardX/device for recent kernels.
The ACCESS check honors the variable substutition now. Added $config{key}
substitution.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2009-04-30 11:26:15 +02:00
parent 42ae1e6f1b
commit 94ac54bff1
3 changed files with 34 additions and 5 deletions

View file

@ -279,7 +279,7 @@
<listitem> <listitem>
<para>The relative path to sysfs subsystem specifying <para>The relative path to sysfs subsystem specifying
the root directory of a soundcard device. Usually, the root directory of a soundcard device. Usually,
it should be set to "/class/sound/controlC$cardinfo{card}/device". it should be set to "/class/sound/card$cardinfo{card}/device".
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -462,7 +462,7 @@
<listitem> <listitem>
<para>The relative path to sysfs subsystem specifying <para>The relative path to sysfs subsystem specifying
the root directory of a soundcard device. Usually, the root directory of a soundcard device. Usually,
it should be set to "/class/sound/controlC$cardinfo{card}/device". it should be set to "/class/sound/card$cardinfo{card}/device".
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -552,6 +552,13 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>$config{<replaceable>key</replaceable>}</option>, <option>%g{<replaceable>key</replaceable>}</option></term>
<listitem>
<para>The value of a configuration variable. See CONFIG{} for more details.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>%%</option></term> <term><option>%%</option></term>
<listitem> <listitem>

View file

@ -2,7 +2,9 @@
# See 'man alsactl_init' for syntax. # See 'man alsactl_init' for syntax.
# set root device directory in sysfs for soundcard for ATTR{} command # set root device directory in sysfs for soundcard for ATTR{} command
CONFIG{sysfs_device}="/class/sound/controlC$cardinfo{card}/device" CONFIG{sysfs_device}="/class/sound/card$cardinfo{card}/device"
ACCESS!="$sysfsroot$config{sysfs_device}", \
CONFIG{sysfs_device}="/class/sound/controlC$cardinfo{card}/device"
# test for extra commands # test for extra commands
ENV{CMD}=="help", INCLUDE="help", GOTO="00main_end" ENV{CMD}=="help", INCLUDE="help", GOTO="00main_end"

View file

@ -929,6 +929,7 @@ static void apply_format(struct space *space, char *string, size_t maxsize)
SUBST_ATTR, SUBST_ATTR,
SUBST_SYSFSROOT, SUBST_SYSFSROOT,
SUBST_ENV, SUBST_ENV,
SUBST_CONFIG,
}; };
static const struct subst_map { static const struct subst_map {
char *name; char *name;
@ -941,6 +942,7 @@ static void apply_format(struct space *space, char *string, size_t maxsize)
{ .name = "attr", .fmt = 's', .type = SUBST_ATTR }, { .name = "attr", .fmt = 's', .type = SUBST_ATTR },
{ .name = "sysfsroot", .fmt = 'r', .type = SUBST_SYSFSROOT }, { .name = "sysfsroot", .fmt = 'r', .type = SUBST_SYSFSROOT },
{ .name = "env", .fmt = 'E', .type = SUBST_ENV }, { .name = "env", .fmt = 'E', .type = SUBST_ENV },
{ .name = "config", .fmt = 'g', .type = SUBST_CONFIG },
{ NULL, '\0', 0 } { NULL, '\0', 0 }
}; };
enum subst_type type; enum subst_type type;
@ -1101,6 +1103,16 @@ found:
dbg("substitute env '%s=%s'", attr, pos); dbg("substitute env '%s=%s'", attr, pos);
strlcat(string, pos, maxsize); strlcat(string, pos, maxsize);
break; break;
case SUBST_CONFIG:
if (attr == NULL) {
dbg("missing attribute");
break;
}
pair = value_find(space, attr);
if (pair == NULL)
break;
strlcat(string, pair->value, maxsize);
break;
default: default:
Perror(space, "unknown substitution type=%i", type); Perror(space, "unknown substitution type=%i", type);
break; break;
@ -1520,15 +1532,23 @@ static int parse_line(struct space *space, char *line, size_t linesize)
} }
if (strncasecmp(key, "ACCESS", 6) == 0) { if (strncasecmp(key, "ACCESS", 6) == 0) {
if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) { if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {
if (value[0] == '$') {
strlcpy(string, value, sizeof(string));
apply_format(space, string, sizeof(string));
if (string[0] == '/')
goto __access1;
}
if (value[0] != '/') { if (value[0] != '/') {
strlcpy(string, space->rootdir, sizeof(string)); strlcpy(string, space->rootdir, sizeof(string));
strlcat(string, "/", sizeof(string)); strlcat(string, "/", sizeof(string));
strlcat(string, value, sizeof(string)); strlcat(string, value, sizeof(string));
} else { } else {
strlcat(string, value, sizeof(string)); strlcpy(string, value, sizeof(string));
} }
apply_format(space, string, sizeof(string));
__access1:
count = access(string, F_OK); count = access(string, F_OK);
dbg("access(%s) = %i", value, count); dbg("access(%s) = %i (%s)", string, count, value);
if (op == KEY_OP_MATCH && count != 0) if (op == KEY_OP_MATCH && count != 0)
break; break;
if (op == KEY_OP_NOMATCH && count == 0) if (op == KEY_OP_NOMATCH && count == 0)