/*
 *  Advanced Linux Sound Architecture Control Program
 *  Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
 *                   Jaroslav Kysela <perex@perex.cz>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include "aconfig.h"
#include "version.h"
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <alsa/asoundlib.h>
#include "alsactl.h"


#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a)[0])


static char *id_str(snd_ctl_elem_id_t *id)
{
	static char str[128];
	assert(id);
	sprintf(str, "%i,%i,%i,%s,%i", 
		snd_ctl_elem_id_get_interface(id),
		snd_ctl_elem_id_get_device(id),
		snd_ctl_elem_id_get_subdevice(id),
		snd_ctl_elem_id_get_name(id),
		snd_ctl_elem_id_get_index(id));
	return str;
}

static char *num_str(long n)
{
	static char str[32];
	sprintf(str, "%ld", n);
	return str;
}

static int snd_config_integer_add(snd_config_t *father, char *id, long integer)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_imake_integer(&leaf, id, integer);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	return 0;
}

static int snd_config_integer64_add(snd_config_t *father, char *id, long long integer)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_imake_integer64(&leaf, id, integer);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	return 0;
}

static int snd_config_string_add(snd_config_t *father, const char *id, const char *string)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_imake_string(&leaf, id, string);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	return 0;
}

static int snd_config_compound_add(snd_config_t *father, const char *id, int join,
				   snd_config_t **node)
{
	int err;
	snd_config_t *leaf;
	err = snd_config_make_compound(&leaf, id, join);
	if (err < 0)
		return err;
	err = snd_config_add(father, leaf);
	if (err < 0) {
		snd_config_delete(leaf);
		return err;
	}
	*node = leaf;
	return 0;
}

#define MAX_USER_TLV_SIZE	64

static char *tlv_to_str(unsigned int *tlv)
{
	int i, len = tlv[1] / 4 + 2;
	char *s, *p;

	if (len >= MAX_USER_TLV_SIZE)
		return NULL;
	s = malloc(len * 8 + 1);
	if (! s)
		return NULL;
	p = s;
	for (i = 0; i < len; i++) {
		sprintf(p, "%08x", tlv[i]);
		p += 8;
	}
	return s;
}

static unsigned int *str_to_tlv(const char *s)
{
	int i, j, c, len;
	unsigned int *tlv;
			
	len = strlen(s);
	if (len % 8) /* aligned to 4 bytes (= 8 letters) */
		return NULL;
	len /= 8;
	if (len > MAX_USER_TLV_SIZE)
		return NULL;
	tlv = malloc(sizeof(int) * len);
	if (! tlv)
		return NULL;
	for (i = 0; i < len; i++) {
		tlv[i] = 0;
		for (j = 0; j < 8; j++) {
			if ((c = hextodigit(*s++)) < 0) {
				free(tlv);
				return NULL;
			}
			tlv[i] = (tlv[i] << 4) | c;
		}
	}
	return tlv;
}

/*
 * add the TLV string, dB ranges, and dB values to comment fields
 */
static int add_tlv_comments(snd_ctl_t *handle, snd_ctl_elem_id_t *id,
			    snd_ctl_elem_info_t *info, snd_ctl_elem_value_t *ctl,
			    snd_config_t *comment)
{
	unsigned int tlv[MAX_USER_TLV_SIZE];
	unsigned int *db;
	long rangemin, rangemax;
	long dbmin, dbmax, dbgain;
	snd_config_t *value;
	unsigned int i, count;
	int err;

	if (snd_ctl_elem_tlv_read(handle, id, tlv, sizeof(tlv)) < 0)
		return 0; /* ignore error */

	if (snd_ctl_elem_info_is_tlv_writable(info)) {
		char *s = tlv_to_str(tlv);
		if (s) {
			err = snd_config_string_add(comment, "tlv", s);
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
			free(s);
		}
	}

	err = snd_tlv_parse_dB_info(tlv, sizeof(tlv), &db);
	if (err <= 0)
		return 0;

	rangemin = snd_ctl_elem_info_get_min(info);
	rangemax = snd_ctl_elem_info_get_max(info);
	snd_tlv_get_dB_range(db, rangemin, rangemax, &dbmin, &dbmax);
	if (err < 0)
		return err;
	snd_config_integer_add(comment, "dbmin", dbmin);
	snd_config_integer_add(comment, "dbmax", dbmax);

	if (snd_ctl_elem_info_get_type(info) == SND_CTL_ELEM_TYPE_INTEGER) {
		err = snd_config_compound_add(comment, "dbvalue", 1, &value);
		if (err < 0) {
			error("snd_config_compound_add: %s", snd_strerror(err));
			return err;
		}
		count = snd_ctl_elem_info_get_count(info);
		for (i = 0; i < count; i++) {
			err = snd_tlv_convert_to_dB(db, rangemin, rangemax,
					snd_ctl_elem_value_get_integer(ctl, i), &dbgain);
			if (err < 0) {
				error("snd_tlv_convert_to_dB: %s", snd_strerror(err));
				return err;
			}
			err = snd_config_integer_add(value, num_str(i), dbgain);
			if (err < 0) {
				error("snd_config_integer_add: %s", snd_strerror(err));
				return err;
			}
		}
	}
	return 0;
}

static int get_control(snd_ctl_t *handle, snd_ctl_elem_id_t *id, snd_config_t *top)
{
	snd_ctl_elem_value_t *ctl;
	snd_ctl_elem_info_t *info;
	snd_config_t *control, *comment, *item, *value;
	const char *s;
	char buf[256];
	unsigned int idx;
	int err;
	unsigned int device, subdevice, index;
	const char *name;
	snd_ctl_elem_type_t type;
	unsigned int count;
	snd_ctl_elem_value_alloca(&ctl);
	snd_ctl_elem_info_alloca(&info);
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_info(handle, info);
	if (err < 0) {
		error("Cannot read control info '%s': %s", id_str(id), snd_strerror(err));
		return err;
	}

	if (!snd_ctl_elem_info_is_readable(info))
		return 0;
	snd_ctl_elem_value_set_id(ctl, id);
	err = snd_ctl_elem_read(handle, ctl);
	if (err < 0) {
		error("Cannot read control '%s': %s", id_str(id), snd_strerror(err));
		return err;
	}

	err = snd_config_compound_add(top, num_str(snd_ctl_elem_info_get_numid(info)), 0, &control);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		return err;
	}
	err = snd_config_make_compound(&comment, "comment", 0);
	if (err < 0) {
		error("snd_config_make_compound: %s", snd_strerror(err));
		return err;
	}

	buf[0] = '\0';
	buf[1] = '\0';
	if (snd_ctl_elem_info_is_readable(info))
		strcat(buf, " read");
	if (snd_ctl_elem_info_is_writable(info))
		strcat(buf, " write");
	if (snd_ctl_elem_info_is_inactive(info))
		strcat(buf, " inactive");
	if (snd_ctl_elem_info_is_volatile(info))
		strcat(buf, " volatile");
	if (snd_ctl_elem_info_is_locked(info))
		strcat(buf, " locked");
	if (snd_ctl_elem_info_is_user(info))
		strcat(buf, " user");
	err = snd_config_string_add(comment, "access", buf + 1);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}

	type = snd_ctl_elem_info_get_type(info);
	device = snd_ctl_elem_info_get_device(info);
	subdevice = snd_ctl_elem_info_get_subdevice(info);
	index = snd_ctl_elem_info_get_index(info);
	name = snd_ctl_elem_info_get_name(info);
	count = snd_ctl_elem_info_get_count(info);
	s = snd_ctl_elem_type_name(type);
	err = snd_config_string_add(comment, "type", s);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	err = snd_config_integer_add(comment, "count", count);
	if (err < 0) {
		error("snd_config_integer_add: %s", snd_strerror(err));
		return err;
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
	{
		long min = snd_ctl_elem_info_get_min(info);
		long max = snd_ctl_elem_info_get_max(info);
		long step = snd_ctl_elem_info_get_step(info);
		if (step)
			sprintf(buf, "%li - %li (step %li)", min, max, step);
		else
			sprintf(buf, "%li - %li", min, max);
		err = snd_config_string_add(comment, "range", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		if (snd_ctl_elem_info_is_tlv_readable(info)) {
			err = add_tlv_comments(handle, id, info, ctl, comment);
			if (err < 0)
				return err;
		}
		break;
	}
	case SND_CTL_ELEM_TYPE_INTEGER64:
	{
		long long min = snd_ctl_elem_info_get_min64(info);
		long long max = snd_ctl_elem_info_get_max64(info);
		long long step = snd_ctl_elem_info_get_step64(info);
		if (step)
			sprintf(buf, "%Li - %Li (step %Li)", min, max, step);
		else
			sprintf(buf, "%Li - %Li", min, max);
		err = snd_config_string_add(comment, "range", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		break;
	}
	case SND_CTL_ELEM_TYPE_ENUMERATED:
	{
		unsigned int items;
		err = snd_config_compound_add(comment, "item", 1, &item);
		if (err < 0) {
			error("snd_config_compound_add: %s", snd_strerror(err));
			return err;
		}
		items = snd_ctl_elem_info_get_items(info);
		for (idx = 0; idx < items; idx++) {
			snd_ctl_elem_info_set_item(info, idx);
			err = snd_ctl_elem_info(handle, info);
			if (err < 0) {
				error("snd_ctl_card_info: %s", snd_strerror(err));
				return err;
			}
			err = snd_config_string_add(item, num_str(idx), snd_ctl_elem_info_get_item_name(info));
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	}
	default:
		break;
	}
	s = snd_ctl_elem_iface_name(snd_ctl_elem_info_get_interface(info));
	err = snd_config_string_add(control, "iface", s);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	if (device != 0) {
		err = snd_config_integer_add(control, "device", device);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}
	if (subdevice != 0) {
		err = snd_config_integer_add(control, "subdevice", subdevice);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}
	err = snd_config_string_add(control, "name", name);
	if (err < 0) {
		error("snd_config_string_add: %s", snd_strerror(err));
		return err;
	}
	if (index != 0) {
		err = snd_config_integer_add(control, "index", index);
		if (err < 0) {
			error("snd_config_integer_add: %s", snd_strerror(err));
			return err;
		}
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BYTES:
	case SND_CTL_ELEM_TYPE_IEC958:
	{
		size_t size = type == SND_CTL_ELEM_TYPE_BYTES ?
			count : sizeof(snd_aes_iec958_t);
		char buf[size * 2 + 1];
		char *p = buf;
		char *hex = "0123456789abcdef";
		const unsigned char *bytes = 
		  (const unsigned char *)snd_ctl_elem_value_get_bytes(ctl);
		for (idx = 0; idx < size; idx++) {
			int v = bytes[idx];
			*p++ = hex[v >> 4];
			*p++ = hex[v & 0x0f];
		}
		*p = '\0';
		err = snd_config_string_add(control, "value", buf);
		if (err < 0) {
			error("snd_config_string_add: %s", snd_strerror(err));
			return err;
		}
		goto finish;
	}
	default:
		break;
	}

	if (count == 1) {
		switch (type) {
		case SND_CTL_ELEM_TYPE_BOOLEAN:
			err = snd_config_string_add(control, "value", snd_ctl_elem_value_get_boolean(ctl, 0) ? "true" : "false");
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
			goto finish;
		case SND_CTL_ELEM_TYPE_INTEGER:
			err = snd_config_integer_add(control, "value", snd_ctl_elem_value_get_integer(ctl, 0));
			if (err < 0) {
				error("snd_config_integer_add: %s", snd_strerror(err));
				return err;
			}
			goto finish;
		case SND_CTL_ELEM_TYPE_INTEGER64:
			err = snd_config_integer64_add(control, "value", snd_ctl_elem_value_get_integer64(ctl, 0));
			if (err < 0) {
				error("snd_config_integer64_add: %s", snd_strerror(err));
				return err;
			}
			goto finish;
		case SND_CTL_ELEM_TYPE_ENUMERATED:
		{
			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, 0);
			snd_config_t *c;
			err = snd_config_search(item, num_str(v), &c);
			if (err == 0) {
				err = snd_config_get_string(c, &s);
				assert(err == 0);
				err = snd_config_string_add(control, "value", s);
			} else {
				err = snd_config_integer_add(control, "value", v);
			}
			if (err < 0)
				error("snd_config add: %s", snd_strerror(err));
			goto finish;
		}
		default:
			error("Unknown control type: %d\n", type);
			return -EINVAL;
		}
	}

	err = snd_config_compound_add(control, "value", 1, &value);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		return err;
	}

	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_string_add(value, num_str(idx), snd_ctl_elem_value_get_boolean(ctl, idx) ? "true" : "false");
			if (err < 0) {
				error("snd_config_string_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_integer_add(value, num_str(idx), snd_ctl_elem_value_get_integer(ctl, idx));
			if (err < 0) {
				error("snd_config_integer_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		for (idx = 0; idx < count; idx++) {
			err = snd_config_integer64_add(value, num_str(idx), snd_ctl_elem_value_get_integer64(ctl, idx));
			if (err < 0) {
				error("snd_config_integer64_add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		for (idx = 0; idx < count; idx++) {
			unsigned int v = snd_ctl_elem_value_get_enumerated(ctl, idx);
			snd_config_t *c;
			err = snd_config_search(item, num_str(v), &c);
			if (err == 0) {
				err = snd_config_get_string(c, &s);
				assert(err == 0);
				err = snd_config_string_add(value, num_str(idx), s);
			} else {
				err = snd_config_integer_add(value, num_str(idx), v);
			}
			if (err < 0) {
				error("snd_config add: %s", snd_strerror(err));
				return err;
			}
		}
		break;
	default:
		error("Unknown control type: %d\n", type);
		return -EINVAL;
	}
	
finish:
	err = snd_config_add(control, comment);
	if (err < 0) {
		error("snd_config_add: %s", snd_strerror(err));
		return err;
	}
	return 0;
}
	
static int get_controls(int cardno, snd_config_t *top)
{
	snd_ctl_t *handle;
	snd_ctl_card_info_t *info;
	snd_config_t *state, *card, *control;
	snd_ctl_elem_list_t *list;
	snd_ctl_elem_id_t *elem_id;
	unsigned int idx;
	int err;
	char name[32];
	unsigned int count;
	const char *id;
	snd_ctl_card_info_alloca(&info);
	snd_ctl_elem_list_alloca(&list);
	snd_ctl_elem_id_alloca(&elem_id);

	sprintf(name, "hw:%d", cardno);
	err = snd_ctl_open(&handle, name, SND_CTL_READONLY);
	if (err < 0) {
		error("snd_ctl_open error: %s", snd_strerror(err));
		return err;
	}
	err = snd_ctl_card_info(handle, info);
	if (err < 0) {
		error("snd_ctl_card_info error: %s", snd_strerror(err));
		goto _close;
	}
	id = snd_ctl_card_info_get_id(info);
	err = snd_config_search(top, "state", &state);
	if (err == 0 &&
	    snd_config_get_type(state) != SND_CONFIG_TYPE_COMPOUND) {
		error("config state node is not a compound");
		err = -EINVAL;
		goto _close;
	}
	if (err < 0) {
		err = snd_config_compound_add(top, "state", 1, &state);
		if (err < 0) {
			error("snd_config_compound_add: %s", snd_strerror(err));
			goto _close;
		}
	}
	err = snd_config_search(state, id, &card);
	if (err == 0 &&
	    snd_config_get_type(card) != SND_CONFIG_TYPE_COMPOUND) {
		error("config state.%s node is not a compound", id);
		err = -EINVAL;
		goto _close;
	}
	if (err < 0) {
		err = snd_config_compound_add(state, id, 0, &card);
		if (err < 0) {
			error("snd_config_compound_add: %s", snd_strerror(err));
			goto _close;
		}
	}
	err = snd_config_search(card, "control", &control);
	if (err == 0) {
		err = snd_config_delete(control);
		if (err < 0) {
			error("snd_config_delete: %s", snd_strerror(err));
			goto _close;
		}
	}
	err = snd_ctl_elem_list(handle, list);
	if (err < 0) {
		error("Cannot determine controls: %s", snd_strerror(err));
		goto _close;
	}
	count = snd_ctl_elem_list_get_count(list);
	err = snd_config_compound_add(card, "control", count > 0, &control);
	if (err < 0) {
		error("snd_config_compound_add: %s", snd_strerror(err));
		goto _close;
	}
	if (count == 0) {
		err = 0;
		goto _close;
	}
	snd_ctl_elem_list_set_offset(list, 0);
	if (snd_ctl_elem_list_alloc_space(list, count) < 0) {
		error("No enough memory...");
		goto _close;
	}
	if ((err = snd_ctl_elem_list(handle, list)) < 0) {
		error("Cannot determine controls (2): %s", snd_strerror(err));
		goto _free;
	}
	for (idx = 0; idx < count; ++idx) {
		snd_ctl_elem_list_get_id(list, idx, elem_id);
		err = get_control(handle, elem_id, control);
		if (err < 0)
			goto _free;
	}		
		
	err = 0;
 _free:
	snd_ctl_elem_list_free_space(list);
 _close:
	snd_ctl_close(handle);
	return err;
}

static long config_iface(snd_config_t *n)
{
	long i;
	long long li;
	snd_ctl_elem_iface_t idx; 
	const char *str;
	switch (snd_config_get_type(n)) {
	case SND_CONFIG_TYPE_INTEGER:
		snd_config_get_integer(n, &i);
		return i;
	case SND_CONFIG_TYPE_INTEGER64:
		snd_config_get_integer64(n, &li);
		return li;
	case SND_CONFIG_TYPE_STRING:
		snd_config_get_string(n, &str);
		break;
	default:
		return -1;
	}
	for (idx = 0; idx <= SND_CTL_ELEM_IFACE_LAST; idx++) {
		if (strcasecmp(snd_ctl_elem_iface_name(idx), str) == 0)
			return idx;
	}
	return -1;
}

static int config_bool(snd_config_t *n, int doit)
{
	const char *str;
	long val;
	long long lval;

	switch (snd_config_get_type(n)) {
	case SND_CONFIG_TYPE_INTEGER:
		snd_config_get_integer(n, &val);
		if (val < 0 || val > 1)
			return -1;
		return val;
	case SND_CONFIG_TYPE_INTEGER64:
		snd_config_get_integer64(n, &lval);
		if (lval < 0 || lval > 1)
			return -1;
		return (int) lval;
	case SND_CONFIG_TYPE_STRING:
		snd_config_get_string(n, &str);
		break;
	case SND_CONFIG_TYPE_COMPOUND:
		if (!force_restore || !doit)
			return -1;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_bool(n, doit);
	default:
		return -1;
	}
	if (strcmp(str, "on") == 0 || strcmp(str, "true") == 0)
		return 1;
	if (strcmp(str, "off") == 0 || strcmp(str, "false") == 0)
		return 0;
	return -1;
}

static int config_enumerated(snd_config_t *n, snd_ctl_t *handle,
			     snd_ctl_elem_info_t *info, int doit)
{
	const char *str;
	long val;
	long long lval;
	unsigned int idx, items;

	switch (snd_config_get_type(n)) {
	case SND_CONFIG_TYPE_INTEGER:
		snd_config_get_integer(n, &val);
		return val;
	case SND_CONFIG_TYPE_INTEGER64:
		snd_config_get_integer64(n, &lval);
		return (int) lval;
	case SND_CONFIG_TYPE_STRING:
		snd_config_get_string(n, &str);
		break;
	case SND_CONFIG_TYPE_COMPOUND:
		if (!force_restore || !doit)
			return -1;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_enumerated(n, handle, info, doit);
	default:
		return -1;
	}
	items = snd_ctl_elem_info_get_items(info);
	for (idx = 0; idx < items; idx++) {
		int err;
		snd_ctl_elem_info_set_item(info, idx);
		err = snd_ctl_elem_info(handle, info);
		if (err < 0) {
			error("snd_ctl_elem_info: %s", snd_strerror(err));
			return err;
		}
		if (strcmp(str, snd_ctl_elem_info_get_item_name(info)) == 0)
			return idx;
	}
	return -1;
}

static int config_integer(snd_config_t *n, long *val, int doit)
{
	int err = snd_config_get_integer(n, val);
	if (err < 0 && force_restore && doit) {
		if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND)
			return err;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_integer(n, val, doit);
	}
	return err;
}

static int config_integer64(snd_config_t *n, long long *val, int doit)
{
	int err = snd_config_get_integer64(n, val);
	if (err < 0 && force_restore && doit) {
		if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND)
			return err;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_integer64(n, val, doit);
	}
	return err;
}

static int check_comment_access(snd_config_t *conf, const char *str)
{
	snd_config_iterator_t i, next;

	snd_config_for_each(i, next, conf) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id, *s;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (strcmp(id, "access") == 0) {
			if (snd_config_get_string(n, &s) < 0)
				return 0;
			if (strstr(s, str))
				return 1;
		}
	}
	return 0;
}

/*
 * get the item type from the given comment config
 */
static int get_comment_type(snd_config_t *n)
{
	static const snd_ctl_elem_type_t types[] = {
		SND_CTL_ELEM_TYPE_BOOLEAN,
		SND_CTL_ELEM_TYPE_INTEGER,
		SND_CTL_ELEM_TYPE_ENUMERATED,
		SND_CTL_ELEM_TYPE_BYTES,
		SND_CTL_ELEM_TYPE_IEC958,
		SND_CTL_ELEM_TYPE_INTEGER64,
	};
	const char *type;
	unsigned int i;

	if (snd_config_get_string(n, &type) < 0)
		return -EINVAL;
	for (i = 0; i < ARRAY_SIZE(types); ++i)
		if (strcmp(type, snd_ctl_elem_type_name(types[i])) == 0)
			return types[i];
	return -EINVAL;
}

/*
 * get the value range from the given comment config
 */
static int get_comment_range(snd_config_t *n, int ctype,
			     long *imin, long *imax, long *istep)
{
	const char *s;
	int err;

	if (snd_config_get_string(n, &s) < 0)
		return -EINVAL;
	switch (ctype) {
	case SND_CTL_ELEM_TYPE_INTEGER:
		err = sscanf(s, "%li - %li (step %li)", imin, imax, istep);
		if (err != 3) {
			istep = 0;
			err = sscanf(s, "%li - %li", imin, imax);
			if (err != 2)
				return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

struct string_array {
	unsigned int count;
	const char **strings;
};

static int get_comment_items(snd_config_t *n, struct string_array *items)
{
	snd_config_iterator_t it, next;
	unsigned int i;
	int err;

	snd_config_for_each(it, next, n) {
		snd_config_t *item = snd_config_iterator_entry(it);
		const char *id;
		unsigned int numid;

		if (snd_config_get_id(item, &id) < 0)
			return -EINVAL;
		numid = atoi(id);
		if (numid > 999999)
			return -EINVAL;

		if (numid >= items->count) {
			const char **strings = realloc(items->strings, (numid + 1) * sizeof(char *));
			if (!strings)
				return -ENOMEM;
			for (i = items->count; i < numid + 1; ++i)
				strings[i] = NULL;
			items->count = numid + 1;
			items->strings = strings;
		}
		err = snd_config_get_string(item, &items->strings[numid]);
		if (err < 0)
			return err;
	}

	for (i = 0; i < items->count; ++i)
		if (!items->strings[i])
			return -EINVAL;

	return 0;
}

static int add_user_control(snd_ctl_t *handle, snd_ctl_elem_info_t *info, snd_config_t *conf)
{
	snd_ctl_elem_id_t *id;
	snd_config_iterator_t i, next;
	long imin, imax, istep;
	snd_ctl_elem_type_t ctype;
	unsigned int count;
	struct string_array enum_items;
	int err;
	unsigned int *tlv;

	imin = imax = istep = 0;
	count = 0;
	ctype = SND_CTL_ELEM_TYPE_NONE;
	enum_items.count = 0;
	enum_items.strings = NULL;
	tlv = NULL;
	snd_config_for_each(i, next, conf) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (strcmp(id, "type") == 0) {
			err = get_comment_type(n);
			if (err < 0)
				goto error;
			ctype = err;
			continue;
		}
		if (strcmp(id, "range") == 0) {
			err = get_comment_range(n, ctype, &imin, &imax, &istep);
			if (err < 0)
				goto error;
			continue;
		}
		if (strcmp(id, "count") == 0) {
			long v;
			if ((err = snd_config_get_integer(n, &v)) < 0)
				goto error;
			count = v;
			continue;
		}
		if (strcmp(id, "item") == 0) {
			err = get_comment_items(n, &enum_items);
			if (err < 0)
				goto error;
			continue;
		}
		if (strcmp(id, "tlv") == 0) {
			const char *s;
			if ((err = snd_config_get_string(n, &s)) < 0)
				goto error;
			if (tlv)
				free(tlv);
			if ((tlv = str_to_tlv(s)) == NULL) {
				err = -EINVAL;
				goto error;
			}
			continue;
		}
	}

	snd_ctl_elem_id_alloca(&id);
	snd_ctl_elem_info_get_id(info, id);
	if (count <= 0)
		count = 1;
	switch (ctype) {
	case SND_CTL_ELEM_TYPE_INTEGER:
		if (imin > imax || istep > imax - imin) {
			err = -EINVAL;
			goto error;
		}
		err = snd_ctl_elem_add_integer(handle, id, count, imin, imax, istep);
		if (err < 0)
			goto error;
		if (tlv)
			snd_ctl_elem_tlv_write(handle, id, tlv);
		break;
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		err = snd_ctl_elem_add_boolean(handle, id, count);
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		err = snd_ctl_elem_add_enumerated(handle, id, count,
						  enum_items.count, enum_items.strings);
		break;
	case SND_CTL_ELEM_TYPE_IEC958:
		err = snd_ctl_elem_add_iec958(handle, id);
		break;
	default:
		err = -EINVAL;
		break;
	}

 error:
	free(tlv);
	free(enum_items.strings);
	if (err < 0)
		return err;
	return snd_ctl_elem_info(handle, info);
}

/*
 * check whether the config item has the same of compatible type
 */
static int check_comment_type(snd_config_t *conf, int type)
{
	snd_config_t *n;
	int ctype;

	if (snd_config_search(conf, "type", &n) < 0)
		return 0; /* not defined */
	ctype = get_comment_type(n);
	if (ctype == type)
		return 0;
	if ((ctype == SND_CTL_ELEM_TYPE_BOOLEAN ||
	     ctype == SND_CTL_ELEM_TYPE_INTEGER ||
	     ctype == SND_CTL_ELEM_TYPE_INTEGER64 ||
	     ctype == SND_CTL_ELEM_TYPE_ENUMERATED) &&
	    (type == SND_CTL_ELEM_TYPE_BOOLEAN ||
	     type == SND_CTL_ELEM_TYPE_INTEGER ||
	     type == SND_CTL_ELEM_TYPE_INTEGER64 ||
	     type == SND_CTL_ELEM_TYPE_ENUMERATED))
		return 0; /* OK, compatible */
	return -EINVAL;
}

/*
 * convert from an old value to a new value with the same dB level
 */
static int convert_to_new_db(snd_config_t *value, long omin, long omax,
			     long nmin, long nmax,
			     long odbmin, long odbmax,
			     snd_config_t *comment, const char *index,
			     snd_ctl_t *device, snd_ctl_elem_id_t *id,
			     int doit)
{
	snd_config_t *db_node;
	long db, val;
	int err;

	if (snd_config_searchv(comment, &db_node, "dbvalue", index, NULL) < 0 ||
	    snd_config_get_integer(db_node, &db) < 0) {
		err = config_integer(value, &val, doit);
		if (err < 0)
			return err;
		if (val < omin || val > omax)
			return -EINVAL;
		db = ((val - omin) * (odbmax - odbmin)) / (omax - omin) + odbmin;
	}

	err = snd_ctl_convert_from_dB(device, id, db, &val, db > 0);
	if (err < 0)
		return err;
	if (val < nmin)
		val = nmin;
	else if (val > nmax)
		val = nmax;
	return snd_config_set_integer(value, val);
}

/*
 * compare the current value range with the old range in comments.
 * also, if dB information is available, try to compare them.
 * if any change occurs, try to keep the same dB level.
 */
static int check_comment_range(snd_ctl_t *handle, snd_config_t *conf,
			       snd_ctl_elem_info_t *info, snd_config_t *value,
			       int doit)
{
	snd_config_t *n;
	long omin, omax, ostep;
	long nmin, nmax;
	long odbmin, odbmax;
	long ndbmin, ndbmax;
	snd_ctl_elem_id_t *id;

	if (snd_config_search(conf, "range", &n) < 0)
		return 0;
	if (get_comment_range(n, SND_CTL_ELEM_TYPE_INTEGER,
			      &omin, &omax, &ostep) < 0)
		return 0;
	nmin = snd_ctl_elem_info_get_min(info);
	nmax = snd_ctl_elem_info_get_max(info);
	if (omin != nmin && omax != nmax) {
		/* Hey, the range mismatches */
		if (!force_restore || !doit)
			return -EINVAL;
	}
	if (omin >= omax || nmin >= nmax)
		return 0; /* invalid values */

	if (snd_config_search(conf, "dbmin", &n) < 0)
		return 0;
	if (config_integer(n, &odbmin, doit) < 0)
		return 0;
	if (snd_config_search(conf, "dbmax", &n) < 0)
		return 0;
	if (config_integer(n, &odbmax, doit) < 0)
		return 0;
	if (odbmin >= odbmax)
		return 0; /* invalid values */
	snd_ctl_elem_id_alloca(&id);
	snd_ctl_elem_info_get_id(info, id);
	if (snd_ctl_get_dB_range(handle, id, &ndbmin, &ndbmax) < 0)
		return 0;
	if (ndbmin >= ndbmax)
		return 0; /* invalid values */
	if (omin == nmin && omax == nmax &&
	    odbmin == ndbmin && odbmax == ndbmax)
		return 0; /* OK, identical one */

	/* Let's guess the current value from dB range */
	if (snd_config_get_type(value) == SND_CONFIG_TYPE_COMPOUND) {
		snd_config_iterator_t i, next;
		snd_config_for_each(i, next, value) {
			snd_config_t *n = snd_config_iterator_entry(i);
			const char *idxstr;
			if (snd_config_get_id(n, &idxstr) < 0)
				continue;
			convert_to_new_db(n, omin, omax, nmin, nmax,
					  odbmin, odbmax, conf, idxstr,
					  handle, id, doit);
		}
	} else
		convert_to_new_db(value, omin, omax, nmin, nmax,
				  odbmin, odbmax, conf, "0",
				  handle, id, doit);
	return 0;
}

static int restore_config_value(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
				snd_ctl_elem_iface_t type,
				snd_config_t *value,
				snd_ctl_elem_value_t *ctl, int idx,
				int doit)
{
	long val;
	long long lval;
	int err;

	switch (type) {
	case SND_CTL_ELEM_TYPE_BOOLEAN:
		val = config_bool(value, doit);
		if (val >= 0) {
			snd_ctl_elem_value_set_boolean(ctl, idx, val);
			return 1;
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER:
		err = config_integer(value, &val, doit);
		if (err == 0) {
			snd_ctl_elem_value_set_integer(ctl, idx, val);
			return 1;
		}
		break;
	case SND_CTL_ELEM_TYPE_INTEGER64:
		err = config_integer64(value, &lval, doit);
		if (err == 0) {
			snd_ctl_elem_value_set_integer64(ctl, idx, lval);
			return 1;
		}
		break;
	case SND_CTL_ELEM_TYPE_ENUMERATED:
		val = config_enumerated(value, handle, info, doit);
		if (val >= 0) {
			snd_ctl_elem_value_set_enumerated(ctl, idx, val);
			return 1;
		}
		break;
	case SND_CTL_ELEM_TYPE_BYTES:
	case SND_CTL_ELEM_TYPE_IEC958:
		break;
	default:
		cerror(doit, "Unknow control type: %d", type);
		return -EINVAL;
	}
	return 0;
}

static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
				 snd_ctl_elem_iface_t type,
				 snd_config_t *value,
				 snd_ctl_elem_value_t *ctl, int idx,
				 unsigned int numid, int doit)
{
	int err = restore_config_value(handle, info, type, value, ctl, idx, doit);
	long val;

	if (err != 0)
		return err;
	switch (type) {
	case SND_CTL_ELEM_TYPE_BYTES:
	case SND_CTL_ELEM_TYPE_IEC958:
		err = snd_config_get_integer(value, &val);
		if (err < 0 || val < 0 || val > 255) {
			cerror(doit, "bad control.%d.value.%d content", numid, idx);
			return force_restore && doit ? 0 : -EINVAL;
		}
		snd_ctl_elem_value_set_byte(ctl, idx, val);
		return 1;
	default:
		break;
	}
	return 0;
}

static int set_control(snd_ctl_t *handle, snd_config_t *control,
		       int *maxnumid, int doit)
{
	snd_ctl_elem_value_t *ctl;
	snd_ctl_elem_info_t *info;
	snd_config_iterator_t i, next;
	unsigned int numid1;
	snd_ctl_elem_iface_t iface = -1;
	int iface1;
	const char *name1;
	unsigned int numid;
	snd_ctl_elem_type_t type;
	unsigned int count;
	long device = -1;
	long device1;
	long subdevice = -1;
	long subdevice1;
	const char *name = NULL;
	long index1;
	long index = -1;
	snd_config_t *value = NULL;
	snd_config_t *comment = NULL;
	unsigned int idx;
	int err;
	char *set;
	const char *id;
	snd_ctl_elem_value_alloca(&ctl);
	snd_ctl_elem_info_alloca(&info);
	if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {
		cerror(doit, "control is not a compound");
		return -EINVAL;
	}
	err = snd_config_get_id(control, &id);
	if (err < 0) {
		cerror(doit, "unable to get id");
		return -EINVAL;
	}
	numid = atoi(id);
	if ((int)numid > *maxnumid)
		*maxnumid = numid;
	snd_config_for_each(i, next, control) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *fld;
		if (snd_config_get_id(n, &fld) < 0)
			continue;
		if (strcmp(fld, "comment") == 0) {
			if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
				cerror(doit, "control.%d.%s is invalid", numid, fld);
				return -EINVAL;
			}
			comment = n;
			continue;
		}
		if (strcmp(fld, "iface") == 0) {
			iface = (snd_ctl_elem_iface_t)config_iface(n);
			continue;
		}
		if (strcmp(fld, "device") == 0) {
			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
				cerror(doit, "control.%d.%s is invalid", numid, fld);
				return -EINVAL;
			}
			snd_config_get_integer(n, &device);
			continue;
		}
		if (strcmp(fld, "subdevice") == 0) {
			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
				cerror(doit, "control.%d.%s is invalid", numid, fld);
				return -EINVAL;
			}
			snd_config_get_integer(n, &subdevice);
			continue;
		}
		if (strcmp(fld, "name") == 0) {
			if (snd_config_get_type(n) != SND_CONFIG_TYPE_STRING) {
				cerror(doit, "control.%d.%s is invalid", numid, fld);
				return -EINVAL;
			}
			snd_config_get_string(n, &name);
			continue;
		}
		if (strcmp(fld, "index") == 0) {
			if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
				cerror(doit, "control.%d.%s is invalid", numid, fld);
				return -EINVAL;
			}
			snd_config_get_integer(n, &index);
			continue;
		}
		if (strcmp(fld, "value") == 0) {
			value = n;
			continue;
		}
		cerror(doit, "unknown control.%d.%s field", numid, fld);
	}
	if (!value) {
		cerror(doit, "missing control.%d.value", numid);
		return -EINVAL;
	}
	if (device < 0)
		device = 0;
	if (subdevice < 0)
		subdevice = 0;
	if (index < 0)
		index = 0;

	err = -EINVAL;
	if (!force_restore) {
		snd_ctl_elem_info_set_numid(info, numid);
		err = snd_ctl_elem_info(handle, info);
	}
	if (err < 0 && name) {
		snd_ctl_elem_info_set_numid(info, 0);
		snd_ctl_elem_info_set_interface(info, iface);
		snd_ctl_elem_info_set_device(info, device);
		snd_ctl_elem_info_set_subdevice(info, subdevice);
		snd_ctl_elem_info_set_name(info, name);
		snd_ctl_elem_info_set_index(info, index);
		err = snd_ctl_elem_info(handle, info);
		if (err < 0 && comment && check_comment_access(comment, "user")) {
			err = add_user_control(handle, info, comment);
			if (err < 0) {
				cerror(doit, "failed to add user control #%d (%s)",
				       numid, snd_strerror(err));
				return err;
			}
		}
	}
	if (err < 0) {
		cerror(doit, "failed to obtain info for control #%d (%s)", numid, snd_strerror(err));
		return -ENOENT;
	}
	numid1 = snd_ctl_elem_info_get_numid(info);
	iface1 = snd_ctl_elem_info_get_interface(info);
	device1 = snd_ctl_elem_info_get_device(info);
	subdevice1 = snd_ctl_elem_info_get_subdevice(info);
	name1 = snd_ctl_elem_info_get_name(info);
	index1 = snd_ctl_elem_info_get_index(info);
	count = snd_ctl_elem_info_get_count(info);
	type = snd_ctl_elem_info_get_type(info);
	if (err |= numid != numid1 && !force_restore)
		cerror(doit, "warning: numid mismatch (%d/%d) for control #%d", 
		      numid, numid1, numid);
	if (err |= iface != iface1)
		cerror(doit, "warning: iface mismatch (%d/%d) for control #%d", iface, iface1, numid);
	if (err |= device != device1)
		cerror(doit, "warning: device mismatch (%ld/%ld) for control #%d", device, device1, numid);
	if (err |= subdevice != subdevice1)
		cerror(doit, "warning: subdevice mismatch (%ld/%ld) for control #%d", subdevice, subdevice1, numid);
	if (err |= strcmp(name, name1))
		cerror(doit, "warning: name mismatch (%s/%s) for control #%d", name, name1, numid);
	if (err |= index != index1)
		cerror(doit, "warning: index mismatch (%ld/%ld) for control #%d", index, index1, numid);
	if (err < 0) {
		cerror(doit, "failed to obtain info for control #%d (%s)", numid, snd_strerror(err));
		return -ENOENT;
	}

	if (comment) {
		if (check_comment_type(comment, type) < 0)
			cerror(doit, "incompatible field type for control #%d", numid);
		if (type == SND_CTL_ELEM_TYPE_INTEGER) {
			if (check_comment_range(handle, comment, info, value, doit) < 0) {
				cerror(doit, "value range mismatch for control #%d",
				      numid);
				return -EINVAL;
			}
		}
		/* inactive controls are not restored */
		if (comment && check_comment_access(comment, "inactive"))
			return 0;
	}

	if (snd_ctl_elem_info_is_inactive(info) ||
				!snd_ctl_elem_info_is_writable(info))
		return 0;
	snd_ctl_elem_value_set_numid(ctl, numid1);

	if (count == 1) {
		err = restore_config_value(handle, info, type, value, ctl, 0, doit);
		if (err < 0)
			return err;
		if (err > 0)
			goto _ok;
	}
	switch (type) {
	case SND_CTL_ELEM_TYPE_BYTES:
	case SND_CTL_ELEM_TYPE_IEC958:
	{
		const char *buf;
		err = snd_config_get_string(value, &buf);
		if (err >= 0) {
			int c1 = 0;
			int len = strlen(buf);
			unsigned int idx = 0;
			int size = type == SND_CTL_ELEM_TYPE_BYTES ?
				count : sizeof(snd_aes_iec958_t);
			if (size * 2 != len) {
				cerror(doit, "bad control.%d.value contents\n", numid);
				return -EINVAL;
			}
			while (*buf) {
				int c = *buf++;
				if ((c = hextodigit(c)) < 0) {
					cerror(doit, "bad control.%d.value contents\n", numid);
					return -EINVAL;
				}
				if (idx % 2 == 1)
					snd_ctl_elem_value_set_byte(ctl, idx / 2, c1 << 4 | c);
				else
					c1 = c;
				idx++;
			}
			goto _ok;
		}
	}
	default:
		break;
	}
	if (snd_config_get_type(value) != SND_CONFIG_TYPE_COMPOUND) {
		if (!force_restore || !doit) {
			cerror(doit, "bad control.%d.value type", numid);
			return -EINVAL;
		}
		for (idx = 0; idx < count; ++idx) {
			err = restore_config_value2(handle, info, type, value,
						    ctl, idx, numid, doit);
			if (err < 0)
				return err;
		}
		goto _ok;
	}

	set = (char*) alloca(count);
	memset(set, 0, count);
	snd_config_for_each(i, next, value) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		idx = atoi(id);
		if (idx >= count || set[idx]) {
			cerror(doit, "bad control.%d.value index", numid);
			if (!force_restore || !doit)
				return -EINVAL;
			continue;
		}
		err = restore_config_value2(handle, info, type, n,
					    ctl, idx, numid, doit);
		if (err < 0)
			return err;
		if (err > 0)
			set[idx] = 1;
	}
	for (idx = 0; idx < count; ++idx) {
		if (!set[idx]) {
			cerror(doit, "control.%d.value.%d is not specified", numid, idx);
			if (!force_restore || !doit)
				return -EINVAL;
		}
	}

 _ok:
	err = doit ? snd_ctl_elem_write(handle, ctl) : 0;
	if (err < 0) {
		error("Cannot write control '%d:%ld:%ld:%s:%ld' : %s", (int)iface, device, subdevice, name, index, snd_strerror(err));
		return err;
	}
	return 0;
}

static int set_controls(int card, snd_config_t *top, int doit)
{
	snd_ctl_t *handle;
	snd_ctl_card_info_t *info;
	snd_config_t *control;
	snd_config_iterator_t i, next;
	int err, maxnumid = -1;
	char name[32], tmpid[16];
	const char *id;
	snd_ctl_card_info_alloca(&info);

	sprintf(name, "hw:%d", card);
	dbg("device='%s', doit=%i", name, doit);
	err = snd_ctl_open(&handle, name, 0);
	if (err < 0) {
		error("snd_ctl_open error: %s", snd_strerror(err));
		return err;
	}
	err = snd_ctl_card_info(handle, info);
	if (err < 0) {
		error("snd_ctl_card_info error: %s", snd_strerror(err));
		goto _close;
	}
	id = snd_ctl_card_info_get_id(info);
	dbg("card-info-id: '%s'", id);
	err = snd_config_searchv(top, &control, "state", id, "control", 0);
	if (err < 0) {
		if (force_restore) {
			sprintf(tmpid, "card%d", card);
			err = snd_config_searchv(top, &control, "state", tmpid, "control", 0);
			if (! err)
				id = tmpid;
		}
		if (err < 0) {
			fprintf(stderr, "No state is present for card %s\n", id);
			goto _close;
		}
		id = tmpid;
	}
	if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {
		cerror(doit, "state.%s.control is not a compound\n", id);
		return -EINVAL;
	}
	snd_config_for_each(i, next, control) {
		snd_config_t *n = snd_config_iterator_entry(i);
		err = set_control(handle, n, &maxnumid, doit);
		if (err < 0 && (!force_restore || !doit))
			goto _close;
	}

	dbg("maxnumid=%i", maxnumid);
	/* check if we have additional controls in driver */
	/* in this case we should go through init procedure */
	if (!doit && maxnumid >= 0) {
		snd_ctl_elem_info_t *info;
		snd_ctl_elem_info_alloca(&info);
		snd_ctl_elem_info_set_numid(info, maxnumid+1);
		if (snd_ctl_elem_info(handle, info) == 0) {
			/* not very informative */
			/* but value is used for check only */
			err = -EAGAIN;
			dbg("more controls than maxnumid?");
			goto _close;
		}
	}

 _close:
	snd_ctl_close(handle);
	dbg("result code: %i", err);
	return err;
}

int save_state(const char *file, const char *cardname)
{
	int err;
	snd_config_t *config;
	snd_input_t *in;
	snd_output_t *out;
	int stdio;

	err = snd_config_top(&config);
	if (err < 0) {
		error("snd_config_top error: %s", snd_strerror(err));
		return err;
	}
	stdio = !strcmp(file, "-");
	if (!stdio && (err = snd_input_stdio_open(&in, file, "r")) >= 0) {
		err = snd_config_load(config, in);
		snd_input_close(in);
#if 0
		if (err < 0) {
			error("snd_config_load error: %s", snd_strerror(err));
			return err;
		}
#endif
	}

	if (!cardname) {
		int card, first = 1;

		card = -1;
		/* find each installed soundcards */
		while (1) {
			if (snd_card_next(&card) < 0)
				break;
			if (card < 0) {
				if (first) {
					if (ignore_nocards) {
						return 0;
					} else {
						error("No soundcards found...");
						return -ENODEV;
					}
				}
				break;
			}
			first = 0;
			if ((err = get_controls(card, config)))
				return err;
		}
	} else {
		int cardno;

		cardno = snd_card_get_index(cardname);
		if (cardno < 0) {
			error("Cannot find soundcard '%s'...", cardname);
			return cardno;
		}
		if ((err = get_controls(cardno, config))) {
			return err;
		}
	}
	
	if (stdio)
		err = snd_output_stdio_attach(&out, stdout, 0);
	else
		err = snd_output_stdio_open(&out, file, "w");
	if (err < 0) {
		error("Cannot open %s for writing: %s", file, snd_strerror(err));
		return -errno;
	}
	err = snd_config_save(config, out);
	snd_output_close(out);
	if (err < 0)
		error("snd_config_save: %s", snd_strerror(err));
	return 0;
}

int load_state(const char *file, const char *initfile, const char *cardname,
	       int do_init)
{
	int err, finalerr = 0;
	snd_config_t *config;
	snd_input_t *in;
	int stdio;

	err = snd_config_top(&config);
	if (err < 0) {
		error("snd_config_top error: %s", snd_strerror(err));
		return err;
	}
	stdio = !strcmp(file, "-");
	if (stdio)
		err = snd_input_stdio_attach(&in, stdin, 0);
	else
		err = snd_input_stdio_open(&in, file, "r");
	if (err >= 0) {
		err = snd_config_load(config, in);
		snd_input_close(in);
		if (err < 0) {
			error("snd_config_load error: %s", snd_strerror(err));
			return err;
		}
	} else {
		int card, first = 1;
		char cardname1[16];

		error("Cannot open %s for reading: %s", file, snd_strerror(err));
		finalerr = err;
		card = -1;
		/* find each installed soundcards */
		while (1) {
			if (snd_card_next(&card) < 0)
				break;
			if (card < 0)
				break;
			first = 0;
			if (!do_init)
				break;
			sprintf(cardname1, "%i", card);
			err = init(initfile, cardname1);
			if (err < 0) {
				finalerr = err;
				initfailed(card, "init", err);
			}
			initfailed(card, "restore", -ENOENT);
		}
		if (first)
			finalerr = 0;	/* no cards, no error code */
		return finalerr;
	}

	if (!cardname) {
		int card, first = 1;
		char cardname1[16];

		card = -1;
		/* find each installed soundcards */
		while (1) {
			if (snd_card_next(&card) < 0)
				break;
			if (card < 0) {
				if (first) {
					if (ignore_nocards) {
						return 0;
					} else {
						error("No soundcards found...");
						return -ENODEV;
					}
				}
				break;
			}
			first = 0;
			/* do a check if controls matches state file */
 			if (do_init && set_controls(card, config, 0)) {
				sprintf(cardname1, "%i", card);
				err = init(initfile, cardname1);
				if (err < 0) {
					initfailed(card, "init", err);
					finalerr = err;
				}
			}
			if ((err = set_controls(card, config, 1))) {
				if (!force_restore)
					finalerr = err;
				initfailed(card, "restore", err);
			}
		}
	} else {
		int cardno;

		cardno = snd_card_get_index(cardname);
		if (cardno < 0) {
			error("Cannot find soundcard '%s'...", cardname);
			return -ENODEV;
		}
		/* do a check if controls matches state file */
		if (do_init && set_controls(cardno, config, 0)) {
			err = init(initfile, cardname);
			if (err < 0) {
				initfailed(cardno, "init", err);
				finalerr = err;
			}
		}
		if ((err = set_controls(cardno, config, 1))) {
			initfailed(cardno, "restore", err);
			if (!force_restore)
				return err;
		}
	}
	return finalerr;
}
