Annotation of coherent/d/PS2_KERNEL/tools/asymkdev.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * File:       asymkdev.c
        !             3:  *
        !             4:  * Purpose:    read a spec from stdin, ask questions, and make nodes
        !             5:  *
        !             6:  * $Log:       asymkdev.c,v $
        !             7:  * Revision 1.1  92/07/17  15:28:53  bin
        !             8:  * Initial revision
        !             9:  * 
        !            10:  */
        !            11: 
        !            12: /*
        !            13:  * ----------------------------------------------------------------------
        !            14:  * Includes.
        !            15:  */
        !            16: #include <stdio.h>
        !            17: #include <termio.h>
        !            18: #include <sys/ktty.h>
        !            19: #include <sys/asy.h>
        !            20: #include <sys/devices.h>
        !            21: 
        !            22: /*
        !            23:  * ----------------------------------------------------------------------
        !            24:  * Definitions.
        !            25:  *     Constants.
        !            26:  *     Macros with argument lists.
        !            27:  *     Typedefs.
        !            28:  *     Enums.
        !            29:  */
        !            30: #define BSZ            256
        !            31: #define ASYNC_SPECFILE "/etc/default/async"
        !            32: #define ASYNC_MKNODS   "asy_mknod"
        !            33: 
        !            34: #define L_             0
        !            35: #define R_             1
        !            36: #define PL_            2
        !            37: #define PR_            3
        !            38: #define FL_            4
        !            39: #define FR_            5
        !            40: #define FPL_           6
        !            41: #define FPR_           7
        !            42: 
        !            43: #define NO(a,b,c,d)    {use_opt[a]=0;use_opt[b]=0;use_opt[c]=0;use_opt[d]=0;}
        !            44: #define MAX_OPT                8
        !            45: #define prompt         if(!uflag)printf
        !            46: 
        !            47: /*
        !            48:  * ----------------------------------------------------------------------
        !            49:  * Functions.
        !            50:  *     Import Functions.
        !            51:  *     Export Functions.
        !            52:  *     Local Functions.
        !            53:  */
        !            54: void fatal();
        !            55: void g_rec();
        !            56: void get_opts();
        !            57: void m_rec();
        !            58: void make_nodes();
        !            59: void p_rec();
        !            60: void usage();
        !            61: 
        !            62: /*
        !            63:  * ----------------------------------------------------------------------
        !            64:  * Global Data.
        !            65:  *     Import Variables.
        !            66:  *     Export Variables.
        !            67:  *     Local Variables.
        !            68:  */
        !            69: int    line;                   /* line number in input file            */
        !            70: unsigned int   x1,x2,x3,x4,x5,x6,x7;
        !            71: char   *cmd;
        !            72: char   chan_found[MAX_ASY];    /* true if record seen for the channel  */
        !            73: int    port[MAX_ASY];          /* port address for the channel         */
        !            74: char   buf[BSZ];               /* input line buffer                    */
        !            75: char   msg[BSZ];               /* error message line buffer                    */
        !            76: char   expect_chan;            /* number of "M" records expected       */
        !            77: char   uflag;                  /* unprompted mode                              */
        !            78: char   *suffix[MAX_OPT] = {
        !            79:        "l",                    /* L_   */
        !            80:        "r",                    /* R_   */
        !            81:        "pl",                   /* PL_  */
        !            82:        "pr",                   /* PR_  */
        !            83:        "fl",                   /* FL_  */
        !            84:        "fr",                   /* FR_  */
        !            85:        "fpl",                  /* FPL_ */
        !            86:        "fpr"                   /* FPR_ */
        !            87: };
        !            88: char   *ofile, *sfile;
        !            89: unsigned char  nmod, poll, flow;
        !            90: 
        !            91: /*
        !            92:  * ----------------------------------------------------------------------
        !            93:  * Code.
        !            94:  */
        !            95: 
        !            96: /*
        !            97:  * main()
        !            98:  *
        !            99:  * while able to read a line from input
        !           100:  *     call routine to process the record type
        !           101:  */
        !           102: main(argc, argv)
        !           103: int argc;
        !           104: char **argv;
        !           105: {
        !           106:        char    *cp;
        !           107:        FILE    *fp;
        !           108: 
        !           109:        cmd = argv[0];
        !           110: 
        !           111:        if (!isatty(1))
        !           112:                usage();
        !           113: 
        !           114:        /*
        !           115:         * Scan command arguments.
        !           116:         */
        !           117:        while (cp = *++argv) {
        !           118:                if (*cp == '-') {
        !           119:                        while(*++cp) {
        !           120:                                switch (*cp) {
        !           121:                                case 'u':
        !           122:                                        uflag = 1;
        !           123:                                        break;
        !           124:                                default:
        !           125:                                        usage();
        !           126:                                }
        !           127:                        }
        !           128:                } else {
        !           129:                        if (ofile) {
        !           130:                                usage();
        !           131:                        } else {
        !           132:                                if (sfile)
        !           133:                                        ofile = cp;
        !           134:                                else
        !           135:                                        sfile = cp;
        !           136:                        }
        !           137:                }
        !           138:        }
        !           139:        if (!ofile)
        !           140:                ofile = ASYNC_MKNODS;
        !           141:        if (!sfile)
        !           142:                sfile = ASYNC_SPECFILE;
        !           143: 
        !           144:        /*
        !           145:         * Find out which channels are in use.
        !           146:         */
        !           147:        if ((fp = fopen(sfile, "r")) == 0) {
        !           148:                sprintf(msg, "%s: can't open spec file %s", cmd, sfile);
        !           149:                fatal(msg);
        !           150:        }
        !           151:        while (fgets(buf, BSZ, fp)) {
        !           152:                line++;
        !           153:                switch (buf[0]) {
        !           154:                        case 'P':  p_rec();  break;
        !           155:                        case 'G':  g_rec();  break;
        !           156:                        case 'M':  m_rec();  break;
        !           157:                }
        !           158:        }
        !           159:        fclose(fp);
        !           160: 
        !           161:        if (expect_chan) {
        !           162:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
        !           163:                fatal(msg);
        !           164:        }
        !           165: 
        !           166:        make_nodes();
        !           167: 
        !           168:        prompt("Done.\n");
        !           169:        exit(0);
        !           170: }
        !           171: 
        !           172: void
        !           173: p_rec()
        !           174: {
        !           175:        if (expect_chan) {
        !           176:                sprintf(msg, "expecting %d \"M\" entries", expect_chan);
        !           177:                fatal(msg);
        !           178:        }
        !           179: 
        !           180:        /*
        !           181:         * "P" record is:
        !           182:         * P port irq outs excl speed channel nms
        !           183:         * port and outs are in hex, others in decimal
        !           184:         */
        !           185:        if (sscanf(buf+1, "%x%d%x%d%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6,&x7) != 7)
        !           186:                fatal("need 7 parameters");
        !           187: 
        !           188:        if (x6 >= MAX_ASY) {
        !           189:                sprintf(msg, "invalid channel #%d\n", x6);
        !           190:                fatal(msg);
        !           191:        }
        !           192: 
        !           193:        if (chan_found[x6]) {
        !           194:                sprintf(msg, "duplicate channel #%d\n", x6);
        !           195:                fatal(msg);
        !           196:        }
        !           197:        chan_found[x6] = 1;
        !           198:        port[x6] = x1;
        !           199: }
        !           200: 
        !           201: void
        !           202: g_rec()
        !           203: {
        !           204:        if (expect_chan) {
        !           205:                fprintf(stderr, "expecting %d \"M\" entries", expect_chan);
        !           206:                fatal("record out of order");
        !           207:        }
        !           208: 
        !           209:        /*
        !           210:         * "G" record is:
        !           211:         * G port irq outs type number-of-channels nms
        !           212:         * port and outs are in hex, others in decimal
        !           213:         * see asy.h for valid types
        !           214:         */
        !           215:        if (sscanf(buf+1, "%x%d%x%d%d%d",&x1,&x2,&x3,&x4,&x5,&x6) != 6)
        !           216:                fatal("need 6 parameters");
        !           217:        if (x5 >= MAX_ASY || x5 == 0)
        !           218:                fatal("number of channels must be in range 1..8");
        !           219:        expect_chan = x5;
        !           220: }
        !           221: 
        !           222: void
        !           223: usage()
        !           224: {
        !           225:        fprintf(stderr, "Usage: %s [-u] specfile outfile\n", cmd);
        !           226:        exit(1);
        !           227: }
        !           228: 
        !           229: void
        !           230: fatal(s)
        !           231: char *s;
        !           232: {
        !           233:        fprintf(stderr, "%s: line %d  %s\n", cmd, line, s);
        !           234:        exit(1);
        !           235: }
        !           236: 
        !           237: void
        !           238: m_rec()
        !           239: {
        !           240:        if (expect_chan == 0) {
        !           241:                fatal("unexpected \"M\" record");
        !           242:        }
        !           243: 
        !           244:        /*
        !           245:         * "M" record is:
        !           246:         * M port speed slot channel
        !           247:         * port is in hex, speed in decimal
        !           248:         */
        !           249:        if (sscanf(buf+1, "%x%d%d%d",&x1,&x2,&x3,&x4) != 4)
        !           250:                fatal("need 4 parameters");
        !           251: 
        !           252:        if (x4 >= MAX_ASY) {
        !           253:                sprintf(msg, "invalid channel #%d\n", x4);
        !           254:                fatal(msg);
        !           255:        }
        !           256: 
        !           257:        chan_found[x4] = 1;
        !           258:        port[x4] = x1;
        !           259:        expect_chan--;
        !           260: }
        !           261: 
        !           262: void
        !           263: make_nodes()
        !           264: {
        !           265:        char    chan;
        !           266:        char    devname[20] = "";
        !           267:        int     last;
        !           268:        unsigned char   minor;
        !           269:        char    use_opt[MAX_OPT], opt;
        !           270:        FILE    *ofp;
        !           271: 
        !           272:        if ((ofp = fopen(ofile, "w")) == 0) {
        !           273:                sprintf(msg, "%s: can't open outfile %s", cmd, ofile);
        !           274:                fatal(msg);
        !           275:        }
        !           276:        fprintf(ofp,
        !           277:          "set -x\n"
        !           278:          "DEV=${DEV-/dev}\n"
        !           279:          "if [ -d $DEV ]\n"
        !           280:          "then\n"
        !           281:          "\t:\n"
        !           282:          "else\n"
        !           283:          "\techo \"Invalid device directory $DEV\"\n"
        !           284:          "\texit 1\n"
        !           285:          "fi\n");
        !           286: 
        !           287:        line = 0;
        !           288:        for (chan = 0; chan < MAX_ASY; chan++) {
        !           289:                if (chan_found[chan]) {
        !           290:                        /*
        !           291:                         * Make default device name.
        !           292:                         * Add 1 to last character of previous name, with carry.
        !           293:                         * Start with "asy00".
        !           294:                         */
        !           295:                        if (devname[0]) {
        !           296:                                last = strlen(devname) - 1;
        !           297:                                if (last > 0 && devname[last]++ == '9') {
        !           298:                                        devname[last--] = '0';
        !           299:                                        devname[last]++;
        !           300:                                }
        !           301:                        } else {
        !           302:                                strcpy(devname, "asy00");
        !           303:                        }
        !           304:                        prompt("Channel %2d is port %4x\n", chan, port[chan]);
        !           305:                        prompt("Device name [%s]: ", devname);
        !           306:                        line++;
        !           307:                        if (!fgets(buf, BSZ, stdin)) {
        !           308:                                sprintf(msg, "%s: input error at channel %d",
        !           309:                                  cmd, chan);
        !           310:                                fatal(msg);
        !           311:                        }
        !           312:                        sscanf(buf, "%s", devname);
        !           313: 
        !           314:                        /*
        !           315:                         * Get user preferences about which devices to make.
        !           316:                         */
        !           317:                        get_opts(chan);
        !           318: 
        !           319:                        /*
        !           320:                         * Make up to 8 nodes per device.
        !           321:                         */
        !           322:                        for (opt = 0; opt < MAX_OPT; opt++)
        !           323:                                use_opt[opt] = 1;
        !           324:                        if (nmod == 0)
        !           325:                                NO(L_, PL_, FL_, FPL_)
        !           326:                        else if (nmod == 1)
        !           327:                                NO(R_, PR_, FR_, FPR_)
        !           328:                        if (poll == 0)
        !           329:                                NO(PL_, PR_, FPL_, FPR_)
        !           330:                        else if (poll == 1)
        !           331:                                NO(L_, R_, FL_, FR_)
        !           332:                        if (flow == 0)
        !           333:                                NO(FL_, FR_, FPL_, FPR_)
        !           334:                        else if (flow == 1)
        !           335:                                NO(L_, R_, PL_, PR_)
        !           336:                        for (opt = 0; opt < MAX_OPT; opt++)
        !           337:                                if (use_opt[opt]) {
        !           338:                                        minor = chan;
        !           339:                                        if ((opt & 1) == 0)
        !           340:                                                minor |= 0x80;
        !           341:                                        if (opt & 2)
        !           342:                                                minor |= 0x40;
        !           343:                                        if (opt & 4)
        !           344:                                                minor |= 0x20;
        !           345: fprintf(ofp, "/etc/mknod -f $DEV/%s%s c %d %d          || exit 1\n",
        !           346:   devname, suffix[opt], ASY_MAJOR, minor);
        !           347: fprintf(ofp, "/bin/chmog 666 sys sys $DEV/%s%s || exit 1\n",
        !           348:   devname, suffix[opt]);
        !           349:                                }
        !           350:                }
        !           351:        }
        !           352:        fclose(ofp);
        !           353: }
        !           354: 
        !           355: /*
        !           356:  * get_opts()
        !           357:  *
        !           358:  * set nmod, poll, flow
        !           359:  */
        !           360: void
        !           361: get_opts(chan)
        !           362: int chan;
        !           363: {
        !           364:        static char my_opts[20] = "lrin";
        !           365:        char    *cp;
        !           366: 
        !           367:        prompt("options - (l|r) (i|p) (f|n) [%s]: ", my_opts);
        !           368:        line++;
        !           369:        if (!fgets(buf, BSZ, stdin)) {
        !           370:                sprintf(msg, "input error at channel %d", chan);
        !           371:                fatal(msg);
        !           372:        }
        !           373:        sscanf(buf, "%s", my_opts);
        !           374: 
        !           375:        /*
        !           376:         * Must have at least one of each pair of switches.
        !           377:         */
        !           378:        nmod = 0;
        !           379:        poll = 0;
        !           380:        flow = 0;
        !           381:        for (cp = my_opts; *cp; cp++) {
        !           382:                switch (*cp) {
        !           383:                        case 'r': nmod |= 1; break;
        !           384:                        case 'l': nmod |= 2; break;
        !           385:                        case 'i': poll |= 1; break;
        !           386:                        case 'p': poll |= 2; break;
        !           387:                        case 'n': flow |= 1; break;
        !           388:                        case 'f': flow |= 2; break;
        !           389:                        default:
        !           390:                                sprintf(msg,
        !           391:                                  "invalid option [%s],  channel %d",
        !           392:                                  my_opts, chan);
        !           393:                                fatal(msg);
        !           394:                }
        !           395:        }
        !           396:        if (nmod)
        !           397:                nmod--;
        !           398:        else {
        !           399:                sprintf(msg, "missing (l|r) option [%s],  channel %d",
        !           400:                  my_opts, chan);
        !           401:                fatal(msg);
        !           402:        }
        !           403:        if (poll)
        !           404:                poll--;
        !           405:        else {
        !           406:                sprintf(msg, "missing (i|p) option [%s],  channel %d",
        !           407:                  my_opts, chan);
        !           408:                fatal(msg);
        !           409:        }
        !           410:        if (flow)
        !           411:                flow--;
        !           412:        else {
        !           413:                sprintf(msg, "missing (f|n) option [%s],  channel %d",
        !           414:                  my_opts, chan);
        !           415:                fatal(msg);
        !           416:        }
        !           417: }

unix.superglobalmegacorp.com

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