Annotation of coherent/b/bin/stty.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * File:       stty.c
                      3:  *
                      4:  * Purpose:    COH 386 stty command, based on termio
                      5:  *     This version is more S5 compliant than COH 286's was.
                      6:  *     It gets status from stdin, and writes to stdout.
                      7:  *     Using -g flag reports termio contents as hex dump
                      8:  *     Input can be a string of 12 hex numbers separated by colons,
                      9:  *       same as output using -g flag.
                     10:  *
                     11:  * $Log:       stty.c,v $
                     12:  * Revision 1.8  93/09/08  08:52:20  bin
                     13:  * hal:report tabs/-tabs in brief output
                     14:  * 
                     15:  * Revision 1.4  92/08/11  15:59:27  root
                     16:  * COH 4.0.1
                     17:  * 
                     18:  */
                     19: 
                     20: /*
                     21:  * ----------------------------------------------------------------------
                     22:  * Includes.
                     23:  */
                     24: #include <stdio.h>
                     25: #include <termio.h>
                     26: 
                     27: /*
                     28:  * ----------------------------------------------------------------------
                     29:  * Definitions.
                     30:  *     Constants.
                     31:  *     Macros with argument lists.
                     32:  *     Typedefs.
                     33:  *     Enums.
                     34:  */
                     35: #define NAMELN         8
                     36: #define OPTNAMELEN     16
                     37: 
                     38: #define DEL    0x7F
                     39: #define NUL    0
                     40: 
                     41: typedef unsigned char uchar;
                     42: typedef unsigned int  uint;
                     43: typedef unsigned long ulong;
                     44: /*
                     45:  * For fields in c_[iocl]flag field in termio,
                     46:  *     optname is the name of the stty command switch
                     47:  *     mask has 1's where bits are modified
                     48:  *     val has the correct value at the bits in question
                     49:  */
                     50: typedef struct {
                     51:        char    optname[OPTNAMELEN];
                     52:        short   mask;
                     53:        short   val;
                     54: } FLAG_OPT;
                     55: 
                     56: /*
                     57:  * ----------------------------------------------------------------------
                     58:  * Functions.
                     59:  *     Import Functions.
                     60:  *     Export Functions.
                     61:  *     Local Functions.
                     62:  */
                     63: static void baudstr();
                     64: static int c_opt();
                     65: static int combo();
                     66: static void dump_all();
                     67: static void dump_brief();
                     68: static void dump_cc();
                     69: static void dump_ch();
                     70: static void dump_cflag();
                     71: static void dump_hex();
                     72: static void dump_iflag();
                     73: static void dump_lflag();
                     74: static void dump_oflag();
                     75: static int num_opt();
                     76: static void panic();
                     77: static int set_ch();
                     78: static int set_num();
                     79: static int set_speed();
                     80: static void set_hex();
                     81: static int simple();
                     82: 
                     83: /*
                     84:  * ----------------------------------------------------------------------
                     85:  * Global Data.
                     86:  *     Import Variables.
                     87:  *     Export Variables.
                     88:  *     Local Variables.
                     89:  */
                     90: static int gflag;
                     91: static int sflag;      /* true if setting termio rather than getting */
                     92: static struct termio t;
                     93: 
                     94: int    g_argc;
                     95: char   ** g_argv;
                     96: char   lbuf[200];
                     97: 
                     98: FLAG_OPT i_list[] = {
                     99:        { "ignbrk", IGNBRK, IGNBRK },
                    100:        { "-ignbrk", IGNBRK, 0 },
                    101:        { "brkint", BRKINT, BRKINT },
                    102:        { "-brkint", BRKINT, 0 },
                    103:        { "ignpar", IGNPAR, IGNPAR },
                    104:        { "-ignpar", IGNPAR, 0 },
                    105:        { "parmrk", PARMRK, PARMRK },
                    106:        { "-parmrk", PARMRK, 0 },
                    107:        { "inpck", INPCK, INPCK },
                    108:        { "-inpck", INPCK, 0 },
                    109:        { "istrip", ISTRIP, ISTRIP },
                    110:        { "-istrip", ISTRIP, 0 },
                    111:        { "inlcr", INLCR, INLCR },
                    112:        { "-inlcr", INLCR, 0 },
                    113:        { "igncr", IGNCR, IGNCR },
                    114:        { "-igncr", IGNCR, 0 },
                    115:        { "icrnl", ICRNL, ICRNL },
                    116:        { "-icrnl", ICRNL, 0 },
                    117:        { "iuclc", IUCLC, IUCLC },
                    118:        { "-iuclc", IUCLC, 0 },
                    119:        { "ixon", IXON, IXON },
                    120:        { "-ixon", IXON, 0 },
                    121:        { "ixany", IXANY, IXANY },
                    122:        { "-ixany", IXANY, 0 },
                    123:        { "ixoff", IXOFF, IXOFF },
                    124:        { "-ixoff", IXOFF, 0 },
                    125:        { "", 0, 0 }
                    126: };
                    127: FLAG_OPT o_list[] = {
                    128:        { "opost", OPOST, OPOST },
                    129:        { "-opost", OPOST, 0 },
                    130:        { "olcuc", OLCUC, OLCUC },
                    131:        { "-olcuc", OLCUC, 0 },
                    132:        { "onlcr", ONLCR, ONLCR },
                    133:        { "-onlcr", ONLCR, 0 },
                    134:        { "ocrnl", OCRNL, OCRNL },
                    135:        { "-ocrnl", OCRNL, 0 },
                    136:        { "onocr", ONOCR, ONOCR },
                    137:        { "-onocr", ONOCR, 0 },
                    138:        { "onlret", ONLRET, ONLRET },
                    139:        { "-onlret", ONLRET, 0 },
                    140:        { "ofill", OFILL, OFILL },
                    141:        { "-ofill", OFILL, 0 },
                    142:        { "ofdel", OFDEL, OFDEL },
                    143:        { "-ofdel", OFDEL, 0 },
                    144:        { "nl0", NLDLY, NL0 },
                    145:        { "nl1", NLDLY, NL1 },
                    146:        { "cr0", CRDLY, CR0 },
                    147:        { "cr1", CRDLY, CR1 },
                    148:        { "cr2", CRDLY, CR2 },
                    149:        { "cr3", CRDLY, CR3 },
                    150:        { "tab0", TABDLY, TAB0 },
                    151:        { "tab1", TABDLY, TAB1 },
                    152:        { "tab2", TABDLY, TAB2 },
                    153:        { "tab3", TABDLY, TAB3 },
                    154:        { "bs0", BSDLY, BS0 },
                    155:        { "bs1", BSDLY, BS1 },
                    156:        { "vt0", VTDLY, VT0 },
                    157:        { "vt1", VTDLY, VT1 },
                    158:        { "ff0", FFDLY, FF0 },
                    159:        { "ff1", FFDLY, FF1 },
                    160:        { "", 0, 0 }
                    161: };
                    162: FLAG_OPT c_list[] = {
                    163:        { "0", CBAUD, B0 },
                    164:        { "50", CBAUD, B50 },
                    165:        { "75", CBAUD, B75 },
                    166:        { "110", CBAUD, B110 },
                    167:        { "134", CBAUD, B134 },
                    168:        { "150", CBAUD, B150 },
                    169:        { "200", CBAUD, B200 },
                    170:        { "300", CBAUD, B300 },
                    171:        { "600", CBAUD, B600 },
                    172:        { "1200", CBAUD, B1200 },
                    173:        { "1800", CBAUD, B1800 },
                    174:        { "2400", CBAUD, B2400 },
                    175:        { "4800", CBAUD, B4800 },
                    176:        { "9600", CBAUD, B9600 },
                    177:        { "19200", CBAUD, B19200 },
                    178:        { "38400", CBAUD, B38400 },
                    179:        { "cs5", CSIZE, CS5 },
                    180:        { "cs6", CSIZE, CS6 },
                    181:        { "cs7", CSIZE, CS7 },
                    182:        { "cs8", CSIZE, CS8 },
                    183:        { "cstopb", CSTOPB, CSTOPB },
                    184:        { "-cstopb", CSTOPB, 0 },
                    185:        { "cread", CREAD, CREAD },
                    186:        { "-cread", CREAD, 0 },
                    187:        { "parenb", PARENB, PARENB },
                    188:        { "-parenb", PARENB, 0 },
                    189:        { "parodd", PARODD, PARODD },
                    190:        { "-parodd", PARODD, 0 },
                    191:        { "hupcl", HUPCL, HUPCL },
                    192:        { "-hupcl", HUPCL, 0 },
                    193:        { "hup", HUPCL, HUPCL },
                    194:        { "-hup", HUPCL, 0 },
                    195:        { "clocal", CLOCAL, CLOCAL },
                    196:        { "-clocal", CLOCAL, 0 },
                    197:        { "", 0, 0 }
                    198: };
                    199: FLAG_OPT l_list[] = {
                    200:        { "isig", ISIG, ISIG },
                    201:        { "-isig", ISIG, 0 },
                    202:        { "icanon", ICANON, ICANON },
                    203:        { "-icanon", ICANON, 0 },
                    204:        { "xcase", XCASE, XCASE },
                    205:        { "-xcase", XCASE, 0 },
                    206:        { "echo", ECHO, ECHO },
                    207:        { "-echo", ECHO, 0 },
                    208:        { "echoe", ECHOE, ECHOE },
                    209:        { "-echoe", ECHOE, 0 },
                    210:        { "echok", ECHOK, ECHOK },
                    211:        { "-echok", ECHOK, 0 },
                    212:        { "echonl", ECHONL, ECHONL },
                    213:        { "-echonl", ECHONL, 0 },
                    214:        { "noflsh", NOFLSH, NOFLSH },
                    215:        { "-noflsh", NOFLSH, 0 },
                    216:        { "", 0, 0 }
                    217: };
                    218: 
                    219: /*
                    220:  * ----------------------------------------------------------------------
                    221:  * Code.
                    222:  */
                    223: 
                    224: main(argc, argv, envp)
                    225: int argc;
                    226: char ** argv, ** envp;
                    227: {
                    228:        int     argn;
                    229:        int     want_ch = -1;
                    230:        int     want_num = -1;
                    231:        int     want_line = 0;
                    232:        unsigned int    line;
                    233:        char    * arg;
                    234:        int     speed;
                    235: 
                    236:        g_argc = argc;
                    237:        g_argv = argv;
                    238: 
                    239:        if (ioctl(0, TCGETA, &t) == -1)
                    240:                panic("can't get terminal parameters for stdin");
                    241:        /*
                    242:         * Decide which format the command line is:
                    243:         *      stty
                    244:         *      stty -a
                    245:         *      stty -g
                    246:         *      stty x:x:...:x  (12 hex values with colon separators)
                    247:         *      stty arglist...
                    248:         */
                    249:        if (argc == 1) {
                    250:                dump_brief();
                    251:                goto stty_done;
                    252:        }
                    253:        if (argc == 2) {
                    254:                if (strcmp(argv[1], "-a") == 0) {
                    255:                        dump_all();
                    256:                        goto stty_done;
                    257:                }
                    258:                if (strcmp(argv[1], "-g") == 0) {
                    259:                        dump_hex();
                    260:                        goto stty_done;
                    261:                }
                    262:                if (index(argv[1], ':')) {
                    263:                        set_hex();
                    264:                        goto stty_done;
                    265:                }
                    266:        }
                    267:        
                    268:        /*
                    269:         * Process an argument list.
                    270:         * Possible argument formats are:
                    271:         *      nnnn            (decimal baud rate)
                    272:         *      line nnnn       (line discipline spec)
                    273:         *      {intr|quit|erase|kill|eof|eol} {c|^c|^?|^-|0xnn}
                    274:         *      {min|time} {nnn}
                    275:         *      simple_option
                    276:         *      combined_option
                    277:         */
                    278:        for (argn = 1; argn < argc; argn++) {
                    279:                arg = argv[argn];
                    280:                if (want_ch >= 0) {
                    281:                        if (!set_ch(want_ch, arg))
                    282:                                fprintf(stderr,
                    283:                                  "stty: invalid option %s %s\n",
                    284:                                  argv[argn-1], arg);
                    285:                        want_ch = -1;
                    286:                        continue;
                    287:                }
                    288:                if (want_num >= 0) {
                    289:                        if (!set_num(want_num, arg))
                    290:                                fprintf(stderr,
                    291:                                  "stty: invalid option %s %s\n",
                    292:                                  argv[argn-1], arg);
                    293:                        want_num = -1;
                    294:                        continue;
                    295:                }
                    296:                if (want_line) {
                    297:                        if (sscanf(arg, "%d", &line) == 1 && line < 128)
                    298:                                t.c_line = line;
                    299:                        else
                    300:                                fprintf(stderr,
                    301:                                  "stty: invalid option line %s\n", arg);
                    302:                        want_line = 0;
                    303:                        continue;
                    304:                }
                    305: #if 0
                    306:                if (sscanf(arg, "%d", &speed) == 1) {
                    307:                        if (!set_speed(speed))
                    308:                                fprintf(stderr,
                    309:                                  "stty: invalid speed %d\n", speed);
                    310:                        continue;
                    311:                }
                    312: #endif
                    313:                if (strcmp(arg, "line") == 0) {
                    314:                        want_line = 1;
                    315:                        continue;
                    316:                }
                    317:                if ((want_ch = c_opt(arg)) >= 0)
                    318:                        continue;
                    319:                if ((want_num = num_opt(arg)) >= 0)
                    320:                        continue;
                    321:                if (simple(arg, i_list, &t.c_iflag))
                    322:                        continue;
                    323:                if (simple(arg, o_list, &t.c_oflag))
                    324:                        continue;
                    325:                if (simple(arg, c_list, &t.c_cflag))
                    326:                        continue;
                    327:                if (simple(arg, l_list, &t.c_lflag))
                    328:                        continue;
                    329:                if (combo(arg))
                    330:                        continue;
                    331:                fprintf(stderr, "stty: invalid option %s\n", arg);
                    332:        }
                    333:        if (ioctl(0, TCSETA, &t) == -1)
                    334:                panic("can't set terminal parameters");
                    335:        if (want_ch >= 0 || want_line)
                    336:                fprintf(stderr, "stty: incomplete option %s\n", argv[argn-1]);
                    337: stty_done:
                    338:        exit(0);
                    339: }
                    340: 
                    341: /*
                    342:  * dump_all()
                    343:  *
                    344:  * Display all termio settings.
                    345:  */
                    346: void
                    347: dump_all()
                    348: {
                    349:        dump_iflag();
                    350:        dump_oflag();
                    351:        dump_cflag();
                    352:        dump_lflag();
                    353:        printf("line=%d\n", t.c_line);
                    354:        dump_cc();
                    355: }
                    356: 
                    357: void
                    358: dump_iflag()
                    359: {
                    360:        short f = t.c_iflag;
                    361: 
                    362:        lbuf[0] = '\0';
                    363:        strcat(lbuf, (f&IGNBRK)?"ignbrk\t":"-ignbrk\t");
                    364:        strcat(lbuf, (f&BRKINT)?"brkint\t":"-brkint\t");
                    365:        strcat(lbuf, (f&IGNPAR)?"ignpar\t":"-ignpar\t");
                    366:        strcat(lbuf, (f&PARMRK)?"parmrk\t":"-parmrk\t");
                    367:        strcat(lbuf, (f&INPCK)?"inpck\t":"-inpck\t");
                    368:        strcat(lbuf, (f&ISTRIP)?"istrip\t":"-istrip\t");
                    369:        strcat(lbuf, (f&INLCR)?"inlcr\t":"-inlcr\t");
                    370:        strcat(lbuf, (f&IGNCR)?"igncr\n":"-igncr\n");
                    371:        fputs(lbuf, stdout);
                    372: 
                    373:        lbuf[0] = '\0';
                    374:        strcat(lbuf, (f&ICRNL)?"icrnl\t":"-icrnl\t");
                    375:        strcat(lbuf, (f&IUCLC)?"iuclc\t":"-iuclc\t");
                    376:        strcat(lbuf, (f&IXON)?"ixon\t":"-ixon\t");
                    377:        strcat(lbuf, (f&IXANY)?"ixany\t":"-ixany\t");
                    378:        strcat(lbuf, (f&IXOFF)?"ixoff\n":"-ixoff\n");
                    379:        fputs(lbuf, stdout);
                    380: }
                    381: 
                    382: void
                    383: dump_oflag()
                    384: {
                    385:        short f = t.c_oflag;
                    386: 
                    387:        lbuf[0] = '\0';
                    388:        strcat(lbuf, (f&OPOST)?"opost\t":"-opost\t");
                    389:        strcat(lbuf, (f&OLCUC)?"olcuc\t":"-olcuc\t");
                    390:        strcat(lbuf, (f&ONLCR)?"onlcr\t":"-onlcr\t");
                    391:        strcat(lbuf, (f&OCRNL)?"ocrnl\t":"-ocrnl\t");
                    392:        strcat(lbuf, (f&ONOCR)?"onocr\t":"-onocr\t");
                    393:        strcat(lbuf, (f&ONLRET)?"onlret\t":"-onlret\t");
                    394:        strcat(lbuf, (f&OFILL)?"ofill\t":"-ofill\t");
                    395:        strcat(lbuf, (f&OFDEL)?"ofdel\n":"-ofdel\n");
                    396:        fputs(lbuf, stdout);
                    397: 
                    398:        lbuf[0] = '\0';
                    399:        strcat(lbuf, (f&NLDLY)?"nl1\t":"nl0\t");
                    400:        switch(f&CRDLY) {
                    401:        case 0x0000:  strcat(lbuf, "cr0\t");  break;
                    402:        case 0x0200:  strcat(lbuf, "cr1\t");  break;
                    403:        case 0x0400:  strcat(lbuf, "cr2\t");  break;
                    404:        case 0x0600:  strcat(lbuf, "cr3\t");  break;
                    405:        }
                    406:        switch(f&TABDLY) {
                    407:        case 0x0000:  strcat(lbuf, "tab0\t");  break;
                    408:        case 0x0800:  strcat(lbuf, "tab1\t");  break;
                    409:        case 0x1000:  strcat(lbuf, "tab2\t");  break;
                    410:        case 0x1800:  strcat(lbuf, "tab3\t");  break;
                    411:        }
                    412:        strcat(lbuf, (f&BSDLY)?"bs1\t":"bs0\t");
                    413:        strcat(lbuf, (f&VTDLY)?"vt1\t":"vt0\t");
                    414:        strcat(lbuf, (f&FFDLY)?"ff1\n":"ff0\n");
                    415:        fputs(lbuf, stdout);
                    416: }
                    417: 
                    418: void
                    419: dump_cflag()
                    420: {
                    421:        short f = t.c_cflag;
                    422: 
                    423:        lbuf[0] = '\0';
                    424:        baudstr(f);
                    425:        switch(f&CSIZE) {
                    426:        case 0x0000:  strcat(lbuf, "cs5\t");  break;
                    427:        case 0x0010:  strcat(lbuf, "cs6\t");  break;
                    428:        case 0x0020:  strcat(lbuf, "cs7\t");  break;
                    429:        case 0x0030:  strcat(lbuf, "cs8\t");  break;
                    430:        }
                    431:        strcat(lbuf, (f&CSTOPB)?"cstopb\t":"-cstopb\t");
                    432:        strcat(lbuf, (f&CREAD)?"cread\t":"-cread\t");
                    433:        strcat(lbuf, (f&PARENB)?"parenb\t":"-parenb\t");
                    434:        strcat(lbuf, (f&PARODD)?"parodd\t":"-parodd\t");
                    435:        strcat(lbuf, (f&HUPCL)?"hupcl\t":"-hupcl\t");
                    436:        strcat(lbuf, (f&CLOCAL)?"clocal\n":"-clocal\n");
                    437:        fputs(lbuf, stdout);
                    438: }
                    439: 
                    440: void
                    441: dump_lflag()
                    442: {
                    443:        short f = t.c_lflag;
                    444: 
                    445:        lbuf[0] = '\0';
                    446:        strcat(lbuf, (f&ISIG)?"isig\t":"-isig\t");
                    447:        strcat(lbuf, (f&ICANON)?"icanon\t":"-icanon\t");
                    448:        strcat(lbuf, (f&XCASE)?"xcase\t":"-xcase\t");
                    449:        strcat(lbuf, (f&ECHO)?"echo\t":"-echo\t");
                    450:        strcat(lbuf, (f&ECHOE)?"echoe\t":"-echoe\t");
                    451:        strcat(lbuf, (f&ECHOK)?"echok\t":"-echok\t");
                    452:        strcat(lbuf, (f&ECHONL)?"echonl\t":"-echonl\t");
                    453:        strcat(lbuf, (f&NOFLSH)?"noflsh\n":"-noflsh\n");
                    454:        fputs(lbuf, stdout);
                    455: }
                    456: 
                    457: void
                    458: dump_cc()
                    459: {
                    460:        dump_ch("intr", t.c_cc[VINTR]);
                    461:        dump_ch("quit", t.c_cc[VQUIT]);
                    462:        dump_ch("erase", t.c_cc[VERASE]);
                    463:        dump_ch("kill", t.c_cc[VKILL]);
                    464:        if (t.c_lflag & ICANON) {
                    465:                dump_ch("eof", t.c_cc[VEOF]);
                    466:                dump_ch("eol", t.c_cc[VEOL]);
                    467:                dump_ch("eol2", t.c_cc[VEOL2]);
                    468:        } else {
                    469:                printf("min=%d  time=%d  ", t.c_cc[VMIN], t.c_cc[VTIME]);
                    470:                dump_ch("swtch", t.c_cc[VSWTCH]);
                    471:        }
                    472:        putchar('\n');
                    473: }
                    474: 
                    475: void
                    476: dump_ch(tag, ch)
                    477: char   * tag;
                    478: unsigned char  ch;
                    479: {
                    480:        if (ch == '\0')
                    481:                printf("%s=<undef>  ", tag);
                    482:        else if (ch < 0x20)
                    483:                printf("%s=^%c  ", tag, ch|0x60);
                    484: #if 0
                    485:        else if (ch > 0x7f)
                    486:                printf("%s=%x  ", tag, ch);
                    487: #endif
                    488:        else if (ch != 0x7f)
                    489:                printf("%s=%c  ", tag, ch);
                    490:        else
                    491:                printf("%s=DEL  ", tag);
                    492: }
                    493: 
                    494: /*
                    495:  * dump_brief()
                    496:  *
                    497:  * Display names for selected settings.
                    498:  */
                    499: void
                    500: dump_brief()
                    501: {
                    502:        short f;
                    503: 
                    504:        f = t.c_iflag;
                    505:        lbuf[0] = '\0';
                    506:        strcat(lbuf, (f&BRKINT)?"brkint\t":"-brkint\t");
                    507:        strcat(lbuf, (f&INPCK)?"inpck\t":"-inpck\t");
                    508:        strcat(lbuf, (f&ICRNL)?"icrnl\t":"-icrnl\t");
                    509: 
                    510:        f = t.c_oflag;
                    511:        strcat(lbuf, (f&OPOST)?"opost\t":"-opost\t");
                    512:        strcat(lbuf, (f&ONLCR)?"onlcr\t":"-onlcr\t");
                    513:        switch(f&TABDLY) {
                    514:        case 0x0000:  strcat(lbuf, "tab0\n");  break;
                    515:        case 0x0800:  strcat(lbuf, "tab1\n");  break;
                    516:        case 0x1000:  strcat(lbuf, "tab2\n");  break;
                    517:        case 0x1800:  strcat(lbuf, "tab3\n");  break;
                    518:        }
                    519:        fputs(lbuf, stdout);
                    520: 
                    521: 
                    522:        f = t.c_cflag;
                    523:        lbuf[0] = '\0';
                    524:        baudstr(f);
                    525:        strcat(lbuf, (f&PARENB)?"parenb\t":"-parenb\t");
                    526:        strcat(lbuf, (f&PARODD)?"parodd\t":"-parodd\t");
                    527:        strcat(lbuf, (f&HUPCL)?"hupcl\n":"-hupcl\n");
                    528:        fputs(lbuf, stdout);
                    529: 
                    530:        f = t.c_lflag;
                    531:        lbuf[0] = '\0';
                    532:        strcat(lbuf, (f&ICANON)?"icanon\t":"-icanon\t");
                    533:        strcat(lbuf, (f&ECHO)?"echo\t":"-echo\t");
                    534:        strcat(lbuf, (f&ECHOE)?"echoe\t":"-echoe\t");
                    535:        strcat(lbuf, (f&ECHOK)?"echok\n":"-echok\n");
                    536:        fputs(lbuf, stdout);
                    537: 
                    538:        dump_ch("intr", t.c_cc[VINTR]);
                    539:        dump_ch("quit", t.c_cc[VQUIT]);
                    540:        dump_ch("erase", t.c_cc[VERASE]);
                    541:        dump_ch("kill", t.c_cc[VKILL]);
                    542:        putchar('\n');
                    543: }
                    544: 
                    545: /*
                    546:  * set_hex()
                    547:  *
                    548:  * Copy sequence of 12 hex input values to termio struct
                    549:  * and send to device.
                    550:  */
                    551: void
                    552: set_hex()
                    553: {
                    554:        int j[12];      /* need int size for %x input */
                    555: 
                    556:        /*
                    557:         * Arg must be 12 hex numbers separated by colons.
                    558:         */
                    559:        t.c_line = 0;
                    560:        if (12 == sscanf(g_argv[1],
                    561:          "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
                    562:          j,j+1,j+2,j+3,j+4,j+5,
                    563:          j+6,j+7,j+8,j+9,j+10,j+11)) { t.c_iflag = j[0];
                    564:                t.c_oflag = j[1];
                    565:                t.c_cflag = j[2];
                    566:                t.c_lflag = j[3];
                    567:                t.c_cc[0] = j[4];
                    568:                t.c_cc[1] = j[5];
                    569:                t.c_cc[2] = j[6];
                    570:                t.c_cc[3] = j[7];
                    571:                t.c_cc[4] = j[8];
                    572:                t.c_cc[5] = j[9];
                    573:                t.c_cc[6] = j[10];
                    574:                t.c_cc[7] = j[11];
                    575:                if (ioctl(0, TCSETA, &t) == -1)
                    576:                        panic("can't set terminal parameters");
                    577:        } else
                    578:                panic("bad argument - expected 12 hex values");
                    579: }
                    580: 
                    581: /*
                    582:  * dump_hex()
                    583:  *
                    584:  * Dump hex contents of termio struct "t" to stdout.
                    585:  */
                    586: void
                    587: dump_hex()
                    588: {
                    589:        printf("%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
                    590:          t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag,
                    591:          t.c_cc[0], t.c_cc[1], t.c_cc[2], t.c_cc[3],
                    592:          t.c_cc[4], t.c_cc[5], t.c_cc[6], t.c_cc[7]);
                    593: }
                    594: 
                    595: /*
                    596:  * panic()
                    597:  *
                    598:  * Display fatal error message and quit.
                    599:  */
                    600: void
                    601: panic(s)
                    602: char * s;
                    603: {
                    604:        fprintf(stderr, "stty: %s\n", s);
                    605:        exit(1);
                    606: }
                    607: 
                    608: /*
                    609:  * baudstr()
                    610:  *
                    611:  * Append to lbuf the ASCII text for a given baud rate in f.
                    612:  */
                    613: void
                    614: baudstr(f)
                    615: int f;
                    616: {
                    617:        switch(f&CBAUD) {
                    618:        case B0:  strcat(lbuf, "0\t");  break;
                    619:        case B50:  strcat(lbuf, "50\t");  break;
                    620:        case B75:  strcat(lbuf, "75\t");  break;
                    621:        case B110:  strcat(lbuf, "110\t");  break;
                    622:        case B134:  strcat(lbuf, "134\t");  break;
                    623:        case B150:  strcat(lbuf, "150\t");  break;
                    624:        case B200:  strcat(lbuf, "200\t");  break;
                    625:        case B300:  strcat(lbuf, "300\t");  break;
                    626:        case B600:  strcat(lbuf, "600\t");  break;
                    627:        case B1200:  strcat(lbuf, "1200\t");  break;
                    628:        case B1800:  strcat(lbuf, "1800\t");  break;
                    629:        case B2400:  strcat(lbuf, "2400\t");  break;
                    630:        case B4800:  strcat(lbuf, "4800\t");  break;
                    631:        case B9600:  strcat(lbuf, "9600\t");  break;
                    632:        case B19200:  strcat(lbuf, "19200\t");  break;
                    633:        case B38400:  strcat(lbuf, "38400\t");  break;
                    634:        }
                    635: }
                    636: 
                    637: int
                    638: simple(opt, list, flagp)
                    639: char           * opt;
                    640: FLAG_OPT       * list;
                    641: short          * flagp;
                    642: {
                    643:        int     ret = 0;
                    644:        int     i;
                    645: 
                    646:        for (i = 0; list[i].optname[0] && !ret; i++) {
                    647:                if (strcmp(opt, list[i].optname) == 0) {
                    648:                        *flagp &= ~(list[i].mask);
                    649:                        *flagp |= list[i].val;
                    650:                        ret = 1;
                    651:                }
                    652:        }
                    653:        return ret;
                    654: }
                    655: 
                    656: int
                    657: combo(opt)
                    658: char * opt;
                    659: {
                    660:        int     ret = 1;
                    661: 
                    662:        if (strcmp(opt, "sane") == 0) {
                    663:                simple("icrnl", c_list, &t.c_iflag);
                    664:                simple("opost", o_list, &t.c_oflag);
                    665:                simple("onlcr", o_list, &t.c_oflag);
                    666:                simple("isig", l_list, &t.c_lflag);
                    667:                simple("icanon", l_list, &t.c_lflag);
                    668:                simple("-xcase", l_list, &t.c_lflag);
                    669:                simple("echo", l_list, &t.c_lflag);
                    670:                simple("echoe", l_list, &t.c_lflag);
                    671:                simple("echok", l_list, &t.c_lflag);
                    672:                t.c_cc[VERASE] = '\b';
                    673:                goto combo_done;
                    674:        }
                    675:        if (strcmp(opt, "evenp") == 0) {
                    676:                simple("parenb", c_list, &t.c_cflag);
                    677:                simple("-parodd", c_list, &t.c_cflag);
                    678:                simple("cs7", c_list, &t.c_cflag);
                    679:                goto combo_done;
                    680:        }
                    681:        if (strcmp(opt, "parity") == 0) {
                    682:                combo("evenp");
                    683:                goto combo_done;
                    684:        }
                    685:        if (strcmp(opt, "oddp") == 0) {
                    686:                simple("parenb", c_list, &t.c_cflag);
                    687:                simple("parodd", c_list, &t.c_cflag);
                    688:                simple("cs7", c_list, &t.c_cflag);
                    689:                goto combo_done;
                    690:        }
                    691:        if (strcmp(opt, "-parity") == 0) {
                    692:                simple("-parenb", c_list, &t.c_cflag);
                    693:                simple("cs8", c_list, &t.c_cflag);
                    694:                goto combo_done;
                    695:        }
                    696:        if (strcmp(opt, "-evenp") == 0) {
                    697:                simple("-parenb", c_list, &t.c_cflag);
                    698:                simple("cs8", c_list, &t.c_cflag);
                    699:                goto combo_done;
                    700:        }
                    701:        if (strcmp(opt, "-oddp") == 0) {
                    702:                simple("-parenb", c_list, &t.c_cflag);
                    703:                simple("cs8", c_list, &t.c_cflag);
                    704:                goto combo_done;
                    705:        }
                    706:        if (strcmp(opt, "raw") == 0) {
                    707:                t.c_iflag = 0;
                    708:                t.c_oflag &= ~OPOST;
                    709:                t.c_cflag &= ~(PARODD|PARENB);
                    710:                t.c_cflag |= (CS8|CREAD);
                    711:                t.c_lflag &= ~(ECHONL|ISIG|ICANON|XCASE);
                    712:                goto combo_done;
                    713:        }
                    714:        if (strcmp(opt, "-raw") == 0) {
                    715:                t.c_iflag |= BRKINT|IGNPAR|ISTRIP|ICRNL|IXON;
                    716:                t.c_oflag |= OPOST|ONLCR;
                    717:                t.c_cflag |= (PARENB|CS7|CREAD);
                    718:                t.c_iflag |= ISIG|ICANON;
                    719:                goto combo_done;
                    720:        }
                    721:        if (strcmp(opt, "cooked") == 0) {
                    722:                combo("-raw");
                    723:                goto combo_done;
                    724:        }
                    725:        if (strcmp(opt, "nl") == 0) {
                    726:                simple("-icrnl", i_list, &t.c_iflag);
                    727:                simple("-onlcr", o_list, &t.c_oflag);
                    728:                goto combo_done;
                    729:        }
                    730:        if (strcmp(opt, "-nl") == 0) {
                    731:                simple("icrnl", i_list, &t.c_iflag);
                    732:                simple("-inlcr", i_list, &t.c_iflag);
                    733:                simple("-igncr", i_list, &t.c_iflag);
                    734:                simple("onlcr", o_list, &t.c_oflag);
                    735:                simple("-ocrnl", o_list, &t.c_oflag);
                    736:                simple("-onlret", o_list, &t.c_oflag);
                    737:                goto combo_done;
                    738:        }
                    739:        if (strcmp(opt, "lcase") == 0) {
                    740:                t.c_lflag |= XCASE;
                    741:                t.c_iflag |= IUCLC;
                    742:                t.c_oflag |= OLCUC;
                    743:                goto combo_done;
                    744:        }
                    745:        if (strcmp(opt, "-lcase") == 0) {
                    746:                t.c_lflag &= ~XCASE;
                    747:                t.c_iflag &= ~IUCLC;
                    748:                t.c_oflag &= ~OLCUC;
                    749:                goto combo_done;
                    750:        }
                    751:        if (strcmp(opt, "LCASE") == 0) {
                    752:                combo("lcase");
                    753:                goto combo_done;
                    754:        }
                    755:        if (strcmp(opt, "-LCASE") == 0) {
                    756:                combo("-lcase");
                    757:                goto combo_done;
                    758:        }
                    759:        if (strcmp(opt, "tabs") == 0) {
                    760:                simple("tab0", o_list, &t.c_oflag);
                    761:                goto combo_done;
                    762:        }
                    763:        if (strcmp(opt, "-tabs") == 0) {
                    764:                simple("tab3", o_list, &t.c_oflag);
                    765:                goto combo_done;
                    766:        }
                    767:        if (strcmp(opt, "ek") == 0) {
                    768:                t.c_cc[VERASE] = '#';
                    769:                t.c_cc[VKILL] = '@';
                    770:                goto combo_done;
                    771:        }
                    772: 
                    773:        ret = 0;
                    774: combo_done:
                    775:        return ret;
                    776: }
                    777: 
                    778: /*
                    779:  * See if current argument specifies a character option.
                    780:  * If so, return the index into the c_cc array.
                    781:  * Else, return -1.
                    782:  */
                    783: int
                    784: c_opt(opt)
                    785: char * opt;
                    786: {
                    787:        int     ret = -1;
                    788:        int     i;
                    789:        static struct {
                    790:                char    name[NAMELN];
                    791:                int     index;
                    792:        } vlist[] = {
                    793:                { "intr",       0},
                    794:                { "quit",       1},
                    795:                { "erase",      2},
                    796:                { "kill",       3},
                    797:                { "eof",        4},
                    798:                { "eol",        5},
                    799:        };
                    800: 
                    801:        for (i = 0; i < sizeof(vlist)/sizeof(vlist[0]); i++) {
                    802:                if (strcmp(opt, vlist[i].name) == 0) {
                    803:                        ret = vlist[i].index;
                    804:                        break;
                    805:                }
                    806:        }
                    807:        return ret;
                    808: }
                    809: 
                    810: /*
                    811:  * See if current argument specifies a numeric option.
                    812:  * If so, return the index into the c_cc array.
                    813:  * Else, return -1.
                    814:  */
                    815: int
                    816: num_opt(opt)
                    817: char * opt;
                    818: {
                    819:        int     ret = -1;
                    820:        int     i;
                    821:        static struct {
                    822:                char    name[NAMELN];
                    823:                int     index;
                    824:        } vlist[] = {
                    825:                { "min",        4},
                    826:                { "time",       5}
                    827:        };
                    828: 
                    829:        for (i = 0; i < sizeof(vlist)/sizeof(vlist[0]); i++) {
                    830:                if (strcmp(opt, vlist[i].name) == 0) {
                    831:                        ret = vlist[i].index;
                    832:                        break;
                    833:                }
                    834:        }
                    835:        return ret;
                    836: }
                    837: 
                    838: /*
                    839:  * set_ch()
                    840:  *
                    841:  * Given index into c_cc[] array in termio and an argument string,
                    842:  * decode the string and store into specified array element.
                    843:  *
                    844:  * Return 1 if argument passed can be decoded, else return 0.
                    845:  * Valid argument strings are "0xnn", "c", "^c", "^?" denoting DEL,
                    846:  * and "^-" denoting NUL, which means unused.
                    847:  */
                    848: int
                    849: set_ch(want_ch, arg)
                    850: int    want_ch;
                    851: char   * arg;
                    852: {
                    853:        int     ret = 0;
                    854:        unsigned int n;
                    855: 
                    856:        if (strlen(arg) == 1) {
                    857:                n = arg[0];
                    858:                ret = 1;
                    859:                goto set_ch_end;
                    860:        }
                    861:        if (strlen(arg) == 2 && arg[0] == '^') {
                    862:                if (arg[1] == '?')
                    863:                        n = DEL;
                    864:                else if (arg[1] == '-')
                    865:                        n = NUL;
                    866:                else
                    867:                        n = arg[1] & ~0x60;
                    868:                ret = 1;
                    869:                goto set_ch_end;
                    870:        }
                    871:        if (strncmp(arg, "0x", 2) == 0  && sscanf(arg+2, "%x", &n) == 1) {
                    872:                ret = 1;
                    873:                goto set_ch_end;
                    874:        }
                    875: set_ch_end:
                    876:        if (ret)
                    877:                t.c_cc[want_ch] = n;
                    878:        return ret;
                    879: }
                    880: 
                    881: /*
                    882:  * set_num()
                    883:  *
                    884:  * Given index into c_cc[] array in termio and an argument string,
                    885:  * decode the string and store into specified array element.
                    886:  *
                    887:  * Return 1 if argument passed can be decoded, else return 0.
                    888:  * Valid argument strings are "nnn", a decimal value.
                    889:  */
                    890: int
                    891: set_num(want_num, arg)
                    892: int    want_num;
                    893: char   * arg;
                    894: {
                    895:        int     ret = 0;
                    896:        unsigned int n;
                    897: 
                    898:        if (sscanf(arg, "%d", &n) == 1) {
                    899:                ret = 1;
                    900:                t.c_cc[want_num] = n;
                    901:        }
                    902:        return ret;
                    903: }
                    904: 
                    905: #if 0
                    906: /*
                    907:  * set_speed()
                    908:  *
                    909:  * Given baud rate, set speed in termio struct.
                    910:  * Return 1 if valid baud rate, else return 0.
                    911:  */
                    912: int
                    913: set_speed(rate)
                    914: int rate;
                    915: {
                    916:        int     ret = 1;
                    917:        int     x;
                    918: 
                    919:        switch (rate) {
                    920:        case 0:  x = B0;  break;
                    921:        case 50:  x = B50;  break;
                    922:        case 75:  x = B75;  break;
                    923:        case 110:  x = B110;  break;
                    924:        case 134:  x = B134;  break;
                    925:        case 150:  x = B150;  break;
                    926:        case 200:  x = B200;  break;
                    927:        case 300:  x = B300;  break;
                    928:        case 600:  x = B600;  break;
                    929:        case 1200:  x = B1200;  break;
                    930:        case 1800:  x = B1800;  break;
                    931:        case 2400:  x = B2400;  break;
                    932:        case 4800:  x = B4800;  break;
                    933:        case 9600:  x = B9600;  break;
                    934:        case 19200:  x = B19200;  break;
                    935:        case 38400:  x = B38400;  break;
                    936:        default:  ret = 0;
                    937:        }
                    938:        if (ret) {
                    939:                t.c_cflag &= ~CBAUD;
                    940:                t.c_cflag |= x;
                    941:        }
                    942:        return ret;
                    943: }
                    944: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.