if (ndev == 0) errx(1, "no mixer devices configured");
main(argc, argv)	int argc;        char **argv;{	int fd, i, j, ch, pos;	int aflag = 0, wflag = 0, vflag = 0;	char *file;	char *sep = "=";	mixer_devinfo_t dinfo;	mixer_ctrl_t val;	int ndev;	file = getenv("MIXERDEVICE");	if (file == 0)		file = "/dev/mixer";	prog = *argv;	while ((ch = getopt(argc, argv, "af:nvw")) != -1) {		switch(ch) {		case 'a':			aflag++;			break;		case 'w':			wflag++;			break;		case 'v':			vflag++;			break;		case 'n':			sep = 0;			break;		case 'f':			file = optarg;			break;		case '?':		default:		usage:		fprintf(out, "%s [-f file] [-v] [-n] name ...\n", prog);		fprintf(out, "%s [-f file] [-v] [-n] -w name=value ...\n", prog);		fprintf(out, "%s [-f file] [-v] [-n] -a\n", prog);		exit(0);		}	}	argc -= optind;	argv += optind;    	fd = open(file, O_RDWR);	if (fd < 0)		err(1, "%s", file);	for(ndev = 0; ; ndev++) {		dinfo.index = ndev;		if (ioctl(fd, AUDIO_MIXER_DEVINFO, &dinfo) < 0)			break;	}	rfields = calloc(ndev, sizeof *rfields);	fields = calloc(ndev, sizeof *fields);	infos = calloc(ndev, sizeof *infos);	values = calloc(ndev, sizeof *values);	for(i = 0; i < ndev; i++) {		infos[i].index = i;		ioctl(fd, AUDIO_MIXER_DEVINFO, &infos[i]);	}	for(i = 0; i < ndev; i++) {		rfields[i].name = infos[i].label.name;		rfields[i].valp = &values[i];		rfields[i].infp = &infos[i];	}	for(i = 0; i < ndev; i++) {		values[i].dev = i;		values[i].type = infos[i].type;		if (infos[i].type != AUDIO_MIXER_CLASS) {			values[i].un.value.num_channels = 2;			if (ioctl(fd, AUDIO_MIXER_READ, &values[i]) < 0) {				values[i].un.value.num_channels = 1;				if (ioctl(fd, AUDIO_MIXER_READ, &values[i]) < 0)					err(1, "AUDIO_MIXER_READ");			}		}	}	for(j = i = 0; i < ndev; i++) {		if (infos[i].type != AUDIO_MIXER_CLASS &&		    infos[i].type != -1) {			fields[j++] = rfields[i];			for(pos = infos[i].next; pos != AUDIO_MIXER_LAST;			    pos = infos[pos].next) {				fields[j] = rfields[pos];				fields[j].name = catstr(rfields[i].name, 							infos[pos].label.name);				infos[pos].type = -1;				j++;			}		}	}	for(i = 0; i < j; i++) {		int cls = fields[i].infp->mixer_class;		if (cls >= 0 && cls < ndev)			fields[i].name = catstr(infos[cls].label.name, 						fields[i].name);	}	if (argc == 0 && aflag && !wflag) {		for(i = 0; fields[i].name; i++) {			prfield(&fields[i], sep, vflag);			fprintf(out, "\n");		}	} else if (argc > 0 && !aflag) {		struct field *p;		if (wflag) {			while(argc--) {				char *q;				q = strchr(*argv, '=');				if (q) {					*q++ = 0;					p = findfield(*argv);					if (p == 0)						warnx("field %s does not exist", *argv);					else {						val = *p->valp;						if (rdfield(p, q)) {							if (ioctl(fd, AUDIO_MIXER_WRITE, p->valp) < 0)								warn("AUDIO_MIXER_WRITE");							else if (sep) {								*p->valp = val;								prfield(p, ": ", 0);								ioctl(fd, AUDIO_MIXER_READ, p->valp);								printf(" -> ");								prfield(p, 0, 0);								printf("\n");							}						}					}				} else {					warnx("No `=' in %s", *argv);				}				argv++;			}		} else {			while(argc--) {				p = findfield(*argv);				if (p == 0)					warnx("field %s does not exist", *argv);				else					prfield(p, sep, vflag), fprintf(out, "\n");				argv++;			}		}	} else		goto usage;	exit(0);}