[BACK]Return to radioctl.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / radioctl

Annotation of src/usr.bin/radioctl/radioctl.c, Revision 1.12

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