Home | History | Annotate | Line # | Download | only in radioctl
      1  1.13     joerg /* $NetBSD: radioctl.c,v 1.13 2011/09/06 18:27:08 joerg Exp $ */
      2   1.1  augustss /* $OpenBSD: radioctl.c,v 1.5 2001/12/18 18:42:19 mickey Exp $ */
      3   1.1  augustss /* $RuOBSD: radioctl.c,v 1.4 2001/10/20 18:09:10 pva Exp $ */
      4   1.1  augustss 
      5   1.1  augustss /*
      6   1.1  augustss  * Copyright (c) 2001 Vladimir Popov <jumbo (at) narod.ru>
      7   1.1  augustss  * All rights reserved.
      8   1.1  augustss  *
      9   1.1  augustss  * Redistribution and use in source and binary forms, with or without
     10   1.1  augustss  * modification, are permitted provided that the following conditions
     11   1.1  augustss  * are met:
     12   1.1  augustss  * 1. Redistributions of source code must retain the above copyright
     13   1.1  augustss  *    notice, this list of conditions and the following disclaimer.
     14   1.1  augustss  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1  augustss  *    notice, this list of conditions and the following disclaimer in the
     16   1.1  augustss  *    documentation and/or other materials provided with the distribution.
     17   1.1  augustss  *
     18   1.1  augustss  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19   1.1  augustss  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20   1.1  augustss  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21   1.1  augustss  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22   1.1  augustss  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     23   1.1  augustss  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     24   1.1  augustss  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25   1.1  augustss  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     26   1.1  augustss  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     27   1.1  augustss  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28   1.1  augustss  */
     29   1.5       agc #include <sys/cdefs.h>
     30   1.5       agc 
     31   1.5       agc #ifndef lint
     32  1.13     joerg __RCSID("$NetBSD: radioctl.c,v 1.13 2011/09/06 18:27:08 joerg Exp $");
     33   1.5       agc #endif
     34   1.1  augustss 
     35   1.1  augustss #include <sys/ioctl.h>
     36   1.1  augustss #include <sys/radioio.h>
     37   1.1  augustss 
     38   1.1  augustss #include <err.h>
     39   1.1  augustss #include <fcntl.h>
     40   1.1  augustss #include <stdio.h>
     41   1.1  augustss #include <stdlib.h>
     42   1.1  augustss #include <string.h>
     43   1.1  augustss #include <unistd.h>
     44   1.1  augustss 
     45   1.1  augustss #define RADIO_ENV	"RADIODEVICE"
     46   1.1  augustss #define RADIODEVICE	"/dev/radio"
     47   1.1  augustss 
     48  1.13     joerg static const char *varname[] = {
     49   1.1  augustss 	"search",
     50   1.1  augustss #define OPTION_SEARCH		0x00
     51   1.1  augustss 	"volume",
     52   1.1  augustss #define OPTION_VOLUME		0x01
     53   1.1  augustss 	"frequency",
     54   1.1  augustss #define OPTION_FREQUENCY	0x02
     55   1.1  augustss 	"mute",
     56   1.1  augustss #define OPTION_MUTE		0x03
     57   1.1  augustss 	"reference",
     58   1.1  augustss #define OPTION_REFERENCE	0x04
     59   1.1  augustss 	"mono",
     60   1.1  augustss #define OPTION_MONO		0x05
     61   1.1  augustss 	"stereo",
     62   1.1  augustss #define	OPTION_STEREO		0x06
     63   1.1  augustss 	"sensitivity"
     64   1.1  augustss #define	OPTION_SENSITIVITY	0x07
     65   1.1  augustss };
     66   1.1  augustss 
     67   1.1  augustss #define OPTION_NONE		~0u
     68   1.1  augustss #define VALUE_NONE		~0u
     69   1.1  augustss 
     70   1.1  augustss struct opt_t {
     71   1.1  augustss 	char *string;
     72   1.1  augustss 	int option;
     73   1.1  augustss 	int sign;
     74   1.1  augustss #define SIGN_NONE	0
     75   1.1  augustss #define SIGN_PLUS	1
     76   1.1  augustss #define SIGN_MINUS	-1
     77   1.1  augustss 	u_int32_t value;
     78   1.1  augustss };
     79   1.1  augustss 
     80  1.13     joerg static const char *onchar = "on";
     81   1.1  augustss #define ONCHAR_LEN	2
     82  1.13     joerg static const char *offchar = "off";
     83   1.1  augustss #define OFFCHAR_LEN	3
     84   1.1  augustss 
     85   1.1  augustss static struct radio_info ri;
     86   1.1  augustss 
     87   1.1  augustss static int	parse_opt(char *, struct opt_t *);
     88   1.1  augustss 
     89   1.1  augustss static void	print_vars(int);
     90   1.1  augustss static void	do_ioctls(int, struct opt_t *, int);
     91   1.1  augustss 
     92   1.1  augustss static void	print_value(int);
     93   1.1  augustss static void	change_value(const struct opt_t);
     94   1.7       mrg static void	update_value(int, u_int *, u_int);
     95   1.1  augustss 
     96   1.1  augustss static void     warn_unsupported(int);
     97  1.13     joerg __dead static void	usage(void);
     98   1.1  augustss 
     99   1.1  augustss static void	show_verbose(const char *, int);
    100   1.8     lukem static void	show_int_val(u_long, const char *, const char *, int);
    101   1.8     lukem static void	show_float_val(float, const char *, const char *, int);
    102   1.1  augustss static void	show_char_val(const char *, const char *, int);
    103   1.1  augustss static int	str_to_opt(const char *);
    104   1.1  augustss static u_long	str_to_long(char *, int);
    105   1.1  augustss 
    106   1.1  augustss /*
    107   1.1  augustss  * Control behavior of a FM tuner - set frequency, volume etc
    108   1.1  augustss  */
    109   1.1  augustss int
    110   1.1  augustss main(int argc, char **argv)
    111   1.1  augustss {
    112   1.1  augustss 	struct opt_t opt;
    113   1.8     lukem 	const char *radiodev = NULL;
    114   1.1  augustss 	int rd = -1;
    115   1.2    briggs 	int optchar;
    116   1.1  augustss 	char *param = NULL;
    117   1.1  augustss 	int show_vars = 0;
    118   1.1  augustss 	int set_param = 0;
    119   1.1  augustss 	int silent = 0;
    120   1.1  augustss 
    121   1.1  augustss 	if (argc < 2) {
    122   1.1  augustss 		usage();
    123   1.1  augustss 		exit(1);
    124   1.1  augustss 	}
    125   1.1  augustss 
    126   1.1  augustss 	radiodev = getenv(RADIO_ENV);
    127   1.1  augustss 	if (radiodev == NULL)
    128   1.1  augustss 		radiodev = RADIODEVICE;
    129   1.1  augustss 
    130   1.1  augustss 	while ((optchar = getopt(argc, argv, "af:nw:")) != -1) {
    131   1.1  augustss 		switch (optchar) {
    132   1.1  augustss 		case 'a':
    133   1.1  augustss 			show_vars = 1;
    134   1.1  augustss 			break;
    135   1.1  augustss 		case 'f':
    136   1.1  augustss 			radiodev = optarg;
    137   1.1  augustss 			break;
    138   1.1  augustss 		case 'n':
    139   1.1  augustss 			silent = 1;
    140   1.1  augustss 			break;
    141   1.1  augustss 		case 'w':
    142   1.1  augustss 			set_param = 1;
    143   1.1  augustss 			param = optarg;
    144   1.1  augustss 			break;
    145   1.1  augustss 		default:
    146   1.1  augustss 			usage();
    147   1.1  augustss 			/* NOTREACHED */
    148   1.1  augustss 		}
    149   1.1  augustss 	}
    150   1.4  augustss 	argc -= optind;
    151   1.4  augustss 	argv += optind;
    152   1.1  augustss 
    153   1.1  augustss 	rd = open(radiodev, O_RDONLY);
    154   1.1  augustss 	if (rd < 0)
    155   1.1  augustss 		err(1, "%s open error", radiodev);
    156   1.1  augustss 
    157   1.1  augustss 	if (ioctl(rd, RIOCGINFO, &ri) < 0)
    158   1.1  augustss 		err(1, "RIOCGINFO");
    159   1.1  augustss 
    160   1.1  augustss 	if (argc > 1)
    161   1.1  augustss 		if (parse_opt(*(argv + 1), &opt)) {
    162   1.1  augustss 			show_verbose(varname[opt.option], silent);
    163   1.1  augustss 			print_value(opt.option);
    164   1.1  augustss 			free(opt.string);
    165   1.1  augustss 			putchar('\n');
    166   1.1  augustss 		}
    167   1.1  augustss 
    168   1.1  augustss 	if (set_param)
    169   1.1  augustss 		if (parse_opt(param, &opt))
    170   1.1  augustss 			do_ioctls(rd, &opt, silent);
    171   1.1  augustss 
    172   1.1  augustss 	if (show_vars)
    173   1.1  augustss 		print_vars(silent);
    174   1.1  augustss 
    175   1.1  augustss 	if (close(rd) < 0)
    176   1.1  augustss 		warn("%s close error", radiodev);
    177   1.1  augustss 
    178   1.1  augustss 	return 0;
    179   1.1  augustss }
    180   1.1  augustss 
    181   1.1  augustss static void
    182   1.1  augustss usage(void)
    183   1.1  augustss {
    184   1.3    briggs 	const char *progname = getprogname();
    185   1.3    briggs 
    186   1.6      jmmv 	fprintf(stderr, "usage:\t%s %s\n\t%s %s\n\t%s %s\n\t%s %s\n",
    187   1.3    briggs 		progname, "[-n] variable ...",
    188   1.3    briggs 		progname, "[-n] -w name=value ...",
    189   1.3    briggs 		progname, "[-n] -a",
    190   1.3    briggs 		progname, "[-n] -f file");
    191   1.3    briggs 	exit(1);
    192   1.1  augustss }
    193   1.1  augustss 
    194   1.1  augustss static void
    195   1.1  augustss show_verbose(const char *nick, int silent)
    196   1.1  augustss {
    197   1.1  augustss 	if (!silent)
    198   1.1  augustss 		printf("%s=", nick);
    199   1.1  augustss }
    200   1.1  augustss 
    201   1.1  augustss static void
    202   1.1  augustss warn_unsupported(int optval)
    203   1.1  augustss {
    204   1.1  augustss 	warnx("driver does not support `%s'", varname[optval]);
    205   1.1  augustss }
    206   1.1  augustss 
    207   1.1  augustss static void
    208   1.1  augustss do_ioctls(int fd, struct opt_t *o, int silent)
    209   1.1  augustss {
    210   1.1  augustss 	int oval;
    211   1.1  augustss 
    212   1.1  augustss 	if (fd < 0 || o == NULL)
    213   1.1  augustss 		return;
    214   1.1  augustss 
    215   1.1  augustss 	if (o->option == OPTION_SEARCH && !(ri.caps & RADIO_CAPS_HW_SEARCH)) {
    216   1.1  augustss 		warn_unsupported(o->option);
    217   1.1  augustss 		return;
    218   1.1  augustss 	}
    219   1.1  augustss 
    220   1.1  augustss 	oval = o->option == OPTION_SEARCH ? OPTION_FREQUENCY : o->option;
    221   1.1  augustss 	if (!silent)
    222   1.1  augustss 		printf("%s: ", varname[oval]);
    223   1.1  augustss 
    224   1.1  augustss 	print_value(o->option);
    225   1.1  augustss 	printf(" -> ");
    226   1.1  augustss 
    227   1.1  augustss 	if (o->option == OPTION_SEARCH) {
    228   1.1  augustss 
    229   1.1  augustss 		if (ioctl(fd, RIOCSSRCH, &o->value) < 0) {
    230   1.1  augustss 			warn("RIOCSSRCH");
    231   1.1  augustss 			return;
    232   1.1  augustss 		}
    233   1.1  augustss 
    234   1.1  augustss 	} else {
    235   1.1  augustss 
    236   1.1  augustss 		change_value(*o);
    237   1.1  augustss 		if (ioctl(fd, RIOCSINFO, &ri) < 0) {
    238   1.1  augustss 			warn("RIOCSINFO");
    239   1.1  augustss 			return;
    240   1.1  augustss 		}
    241   1.1  augustss 
    242   1.1  augustss 	}
    243   1.1  augustss 
    244   1.1  augustss 	if (ioctl(fd, RIOCGINFO, &ri) < 0) {
    245   1.1  augustss 		warn("RIOCGINFO");
    246   1.1  augustss 		return;
    247   1.1  augustss 	}
    248   1.1  augustss 
    249   1.1  augustss 	print_value(o->option);
    250   1.1  augustss 	putchar('\n');
    251   1.1  augustss }
    252   1.1  augustss 
    253   1.1  augustss static void
    254   1.1  augustss change_value(const struct opt_t o)
    255   1.1  augustss {
    256   1.1  augustss 	int unsupported = 0;
    257   1.1  augustss 
    258   1.1  augustss 	if (o.value == VALUE_NONE)
    259   1.1  augustss 		return;
    260   1.1  augustss 
    261   1.1  augustss 	switch (o.option) {
    262   1.1  augustss 	case OPTION_VOLUME:
    263   1.7       mrg 		update_value(o.sign, (u_int *)&ri.volume, o.value);
    264   1.1  augustss 		break;
    265   1.1  augustss 	case OPTION_FREQUENCY:
    266   1.7       mrg 		update_value(o.sign, (u_int *)&ri.freq, o.value);
    267   1.1  augustss 		break;
    268   1.1  augustss 	case OPTION_REFERENCE:
    269   1.1  augustss 		if (ri.caps & RADIO_CAPS_REFERENCE_FREQ)
    270   1.7       mrg 			update_value(o.sign, (u_int *)&ri.rfreq, o.value);
    271   1.1  augustss 		else
    272   1.1  augustss 			unsupported++;
    273   1.1  augustss 		break;
    274   1.1  augustss 	case OPTION_MONO:
    275   1.1  augustss 		/* FALLTHROUGH */
    276   1.1  augustss 	case OPTION_STEREO:
    277   1.1  augustss 		if (ri.caps & RADIO_CAPS_SET_MONO)
    278   1.1  augustss 			ri.stereo = o.option == OPTION_MONO ? !o.value : o.value;
    279   1.1  augustss 		else
    280   1.1  augustss 			unsupported++;
    281   1.1  augustss 		break;
    282   1.1  augustss 	case OPTION_SENSITIVITY:
    283   1.1  augustss 		if (ri.caps & RADIO_CAPS_LOCK_SENSITIVITY)
    284   1.7       mrg 			update_value(o.sign, (u_int *)&ri.lock, o.value);
    285   1.1  augustss 		else
    286   1.1  augustss 			unsupported++;
    287   1.1  augustss 		break;
    288   1.1  augustss 	case OPTION_MUTE:
    289   1.1  augustss 		ri.mute = o.value;
    290   1.1  augustss 		break;
    291   1.1  augustss 	}
    292   1.1  augustss 
    293   1.1  augustss 	if ( unsupported )
    294   1.1  augustss 		warn_unsupported(o.option);
    295   1.1  augustss }
    296   1.1  augustss 
    297   1.1  augustss /*
    298   1.1  augustss  * Convert string to integer representation of a parameter
    299   1.1  augustss  */
    300   1.1  augustss static int
    301   1.1  augustss str_to_opt(const char *topt)
    302   1.1  augustss {
    303   1.1  augustss 	int res, toptlen, varlen, len, varsize;
    304   1.1  augustss 
    305   1.1  augustss 	if (topt == NULL || *topt == '\0')
    306   1.1  augustss 		return OPTION_NONE;
    307   1.1  augustss 
    308   1.1  augustss 	varsize = sizeof(varname) / sizeof(varname[0]);
    309   1.1  augustss 	toptlen = strlen(topt);
    310   1.1  augustss 
    311   1.1  augustss 	for (res = 0; res < varsize; res++) {
    312   1.1  augustss 		varlen = strlen(varname[res]);
    313   1.1  augustss 		len = toptlen > varlen ? toptlen : varlen;
    314   1.1  augustss 		if (strncmp(topt, varname[res], len) == 0)
    315   1.1  augustss 			return res;
    316   1.1  augustss 	}
    317   1.1  augustss 
    318   1.4  augustss 	warnx("name not found `%s'", topt);
    319   1.1  augustss 	return OPTION_NONE;
    320   1.1  augustss }
    321   1.1  augustss 
    322   1.1  augustss static void
    323   1.7       mrg update_value(int sign, u_int *value, u_int update)
    324   1.1  augustss {
    325   1.1  augustss 	switch (sign) {
    326   1.1  augustss 	case SIGN_NONE:
    327   1.1  augustss 		*value  = update;
    328   1.1  augustss 		break;
    329   1.1  augustss 	case SIGN_PLUS:
    330   1.1  augustss 		*value += update;
    331   1.1  augustss 		break;
    332   1.1  augustss 	case SIGN_MINUS:
    333   1.1  augustss 		*value -= update;
    334   1.1  augustss 		break;
    335   1.1  augustss 	}
    336   1.1  augustss }
    337   1.1  augustss 
    338   1.1  augustss /*
    339   1.1  augustss  * Convert string to unsigned integer
    340   1.1  augustss  */
    341   1.1  augustss static u_long
    342   1.1  augustss str_to_long(char *str, int optval)
    343   1.1  augustss {
    344   1.1  augustss 	u_long val;
    345   1.1  augustss 
    346   1.1  augustss 	if (str == NULL || *str == '\0')
    347   1.1  augustss 		return VALUE_NONE;
    348   1.1  augustss 
    349   1.1  augustss 	if (optval == OPTION_FREQUENCY)
    350   1.1  augustss 		val = (u_long)1000 * atof(str);
    351   1.1  augustss 	else
    352  1.12    plunky 		val = (u_long)strtol(str, NULL, 10);
    353   1.1  augustss 
    354   1.1  augustss 	return val;
    355   1.1  augustss }
    356   1.1  augustss 
    357   1.1  augustss /*
    358   1.1  augustss  * parse string s into struct opt_t
    359   1.1  augustss  * return true on success, false on failure
    360   1.1  augustss  */
    361   1.1  augustss static int
    362   1.1  augustss parse_opt(char *s, struct opt_t *o) {
    363  1.11  christos 	static const char badvalue[] = "bad value `%s'";
    364   1.1  augustss 	char *topt = NULL;
    365   1.1  augustss 	int slen, optlen;
    366   1.1  augustss 
    367   1.1  augustss 	if (s == NULL || *s == '\0' || o == NULL)
    368   1.1  augustss 		return 0;
    369   1.1  augustss 
    370   1.1  augustss 	o->string = NULL;
    371   1.1  augustss 	o->option = OPTION_NONE;
    372   1.1  augustss 	o->value = VALUE_NONE;
    373   1.1  augustss 	o->sign = SIGN_NONE;
    374   1.1  augustss 
    375   1.1  augustss 	slen = strlen(s);
    376   1.1  augustss 	optlen = strcspn(s, "=");
    377   1.1  augustss 
    378   1.1  augustss 	/* Set only o->optval, the rest is missing */
    379   1.1  augustss 	if (slen == optlen) {
    380   1.1  augustss 		o->option = str_to_opt(s);
    381   1.8     lukem 		return o->option == (int)OPTION_NONE ? 0 : 1;
    382   1.1  augustss 	}
    383   1.1  augustss 
    384   1.1  augustss 	if (optlen > slen - 2) {
    385   1.1  augustss 		warnx(badvalue, s);
    386   1.1  augustss 		return 0;
    387   1.1  augustss 	}
    388   1.1  augustss 
    389   1.1  augustss 	slen -= ++optlen;
    390   1.1  augustss 
    391   1.1  augustss 	if ((topt = (char *)malloc(optlen)) == NULL) {
    392   1.1  augustss 		warn("memory allocation error");
    393   1.1  augustss 		return 0;
    394   1.1  augustss 	}
    395   1.1  augustss 	strlcpy(topt, s, optlen);
    396   1.1  augustss 
    397   1.8     lukem 	if ((o->option = str_to_opt(topt)) == (int)OPTION_NONE) {
    398   1.1  augustss 		free(topt);
    399   1.1  augustss 		return 0;
    400   1.1  augustss 	}
    401   1.1  augustss 	o->string = topt;
    402   1.1  augustss 
    403   1.1  augustss 	topt = &s[optlen];
    404   1.1  augustss 	switch (*topt) {
    405   1.1  augustss 	case '+':
    406   1.1  augustss 	case '-':
    407   1.1  augustss 		o->sign = (*topt == '+') ? SIGN_PLUS : SIGN_MINUS;
    408   1.1  augustss 		o->value = str_to_long(&topt[1], o->option);
    409   1.1  augustss 		break;
    410   1.1  augustss 	case 'o':
    411   1.1  augustss 		if (strncmp(topt, offchar,
    412   1.1  augustss 			slen > OFFCHAR_LEN ? slen : OFFCHAR_LEN) == 0)
    413   1.1  augustss 			o->value = 0;
    414   1.1  augustss 		else if (strncmp(topt, onchar,
    415   1.1  augustss 				slen > ONCHAR_LEN ? slen : ONCHAR_LEN) == 0)
    416   1.1  augustss 				o->value = 1;
    417   1.1  augustss 		break;
    418   1.1  augustss 	case 'u':
    419   1.1  augustss 		if (strncmp(topt, "up", slen > 2 ? slen : 2) == 0)
    420   1.1  augustss 			o->value = 1;
    421   1.1  augustss 		break;
    422   1.1  augustss 	case 'd':
    423   1.1  augustss 		if (strncmp(topt, "down", slen > 4 ? slen : 4) == 0)
    424   1.1  augustss 			o->value = 0;
    425   1.1  augustss 		break;
    426   1.1  augustss 	default:
    427   1.1  augustss 		if (*topt > 47 && *topt < 58)
    428   1.1  augustss 			o->value = str_to_long(topt, o->option);
    429   1.1  augustss 		break;
    430   1.1  augustss 	}
    431   1.1  augustss 
    432   1.1  augustss 	if (o->value == VALUE_NONE) {
    433   1.1  augustss 		warnx(badvalue, topt);
    434   1.1  augustss 		return 0;
    435   1.1  augustss 	}
    436   1.1  augustss 
    437   1.1  augustss 	return 1;
    438   1.1  augustss }
    439   1.1  augustss 
    440   1.1  augustss /*
    441   1.1  augustss  * Print current value of the parameter.
    442   1.1  augustss  */
    443   1.1  augustss static void
    444   1.1  augustss print_value(int optval)
    445   1.1  augustss {
    446   1.8     lukem 	if (optval == (int)OPTION_NONE)
    447   1.1  augustss 		return;
    448   1.1  augustss 
    449   1.1  augustss 	switch (optval) {
    450   1.1  augustss 	case OPTION_SEARCH:
    451   1.1  augustss 		/* FALLTHROUGH */
    452   1.1  augustss 	case OPTION_FREQUENCY:
    453   1.1  augustss 		printf("%.2fMHz", (float)ri.freq / 1000.);
    454   1.1  augustss 		break;
    455   1.1  augustss 	case OPTION_REFERENCE:
    456   1.1  augustss 		printf("%ukHz", ri.rfreq);
    457   1.1  augustss 		break;
    458   1.1  augustss 	case OPTION_SENSITIVITY:
    459   1.1  augustss 		printf("%umkV", ri.lock);
    460   1.1  augustss 		break;
    461   1.1  augustss 	case OPTION_MUTE:
    462   1.9     joerg 		printf("%s", ri.mute ? onchar : offchar);
    463   1.1  augustss 		break;
    464   1.1  augustss 	case OPTION_MONO:
    465   1.9     joerg 		printf("%s", ri.stereo ? offchar : onchar);
    466   1.1  augustss 		break;
    467   1.1  augustss 	case OPTION_STEREO:
    468   1.9     joerg 		printf("%s", ri.stereo ? onchar : offchar);
    469   1.1  augustss 		break;
    470   1.1  augustss 	case OPTION_VOLUME:
    471   1.1  augustss 	default:
    472   1.1  augustss 		printf("%u", ri.volume);
    473   1.1  augustss 		break;
    474   1.1  augustss 	}
    475   1.1  augustss }
    476   1.1  augustss 
    477   1.1  augustss static void
    478   1.8     lukem show_int_val(u_long val, const char *nick, const char *append, int silent)
    479   1.1  augustss {
    480   1.1  augustss 	show_verbose(nick, silent);
    481   1.1  augustss 	printf("%lu%s\n", val, append);
    482   1.1  augustss }
    483   1.1  augustss 
    484   1.1  augustss static void
    485   1.8     lukem show_float_val(float val, const char *nick, const char *append, int silent)
    486   1.1  augustss {
    487   1.1  augustss 	show_verbose(nick, silent);
    488   1.1  augustss 	printf("%.2f%s\n", val, append);
    489   1.1  augustss }
    490   1.1  augustss 
    491   1.1  augustss static void
    492   1.1  augustss show_char_val(const char *val, const char *nick, int silent)
    493   1.1  augustss {
    494   1.1  augustss 	show_verbose(nick, silent);
    495   1.1  augustss 	printf("%s\n", val);
    496   1.1  augustss }
    497   1.1  augustss 
    498   1.1  augustss /*
    499   1.1  augustss  * Print all available parameters
    500   1.1  augustss  */
    501   1.1  augustss static void
    502   1.1  augustss print_vars(int silent)
    503   1.1  augustss {
    504   1.4  augustss 	const char *delim;
    505   1.4  augustss 
    506   1.1  augustss 	show_int_val(ri.volume, varname[OPTION_VOLUME], "", silent);
    507   1.1  augustss 	show_float_val((float)ri.freq / 1000., varname[OPTION_FREQUENCY],
    508   1.1  augustss 			"MHz", silent);
    509   1.1  augustss 	show_char_val(ri.mute ? onchar : offchar, varname[OPTION_MUTE], silent);
    510   1.1  augustss 
    511   1.1  augustss 	if (ri.caps & RADIO_CAPS_REFERENCE_FREQ)
    512   1.1  augustss 		show_int_val(ri.rfreq, varname[OPTION_REFERENCE], "kHz", silent);
    513   1.1  augustss 	if (ri.caps & RADIO_CAPS_LOCK_SENSITIVITY)
    514   1.1  augustss 		show_int_val(ri.lock, varname[OPTION_SENSITIVITY], "mkV", silent);
    515   1.1  augustss 
    516   1.1  augustss 	if (ri.caps & RADIO_CAPS_DETECT_SIGNAL) {
    517   1.1  augustss 		show_verbose("signal", silent);
    518   1.1  augustss 		printf("%s\n", ri.info & RADIO_INFO_SIGNAL ? onchar : offchar);
    519   1.1  augustss 	}
    520   1.1  augustss 	if (ri.caps & RADIO_CAPS_DETECT_STEREO) {
    521   1.1  augustss 		show_verbose(varname[OPTION_STEREO], silent);
    522   1.1  augustss 		printf("%s\n", ri.info & RADIO_INFO_STEREO ? onchar : offchar);
    523   1.1  augustss 	}
    524   1.1  augustss 
    525   1.1  augustss 	if (!silent)
    526   1.4  augustss 		printf("card capabilities:");
    527   1.4  augustss 	delim = "";
    528   1.4  augustss 	if (ri.caps & RADIO_CAPS_DETECT_STEREO)
    529   1.4  augustss 		printf("%s stereo detect", delim), delim=",";
    530   1.4  augustss 	if (ri.caps & RADIO_CAPS_DETECT_SIGNAL)
    531   1.4  augustss 		printf("%s signal detect", delim), delim=",";
    532   1.1  augustss 	if (ri.caps & RADIO_CAPS_SET_MONO)
    533   1.4  augustss 		printf("%s manageable mono/stereo", delim), delim=",";
    534   1.1  augustss 	if (ri.caps & RADIO_CAPS_HW_SEARCH)
    535   1.4  augustss 		printf("%s hardware search", delim), delim=",";
    536   1.1  augustss 	if (ri.caps & RADIO_CAPS_HW_AFC)
    537   1.4  augustss 		printf("%s hardware AFC", delim), delim=",";
    538   1.4  augustss 	printf("\n");
    539   1.1  augustss }
    540