Annotation of xinu/con/config.y, revision 1.1.1.2

1.1       root        1: %token DEFBRK COLON OCTAL INTEGER IDENT CSR IVEC OVEC IINT OINT
                      2:        INIT OPEN CLOSE READ WRITE SEEK CNTL IS ON GETC PUTC
                      3: %{
                      4: #include <stdio.h>
                      5: 
                      6: #define        NIL     (dvptr)0
                      7: 
                      8: #define        CONFIGC         "../sys/conf.c"         /* name of .c output    */
                      9: #define        CONFIGH         "../h/conf.h"           /* name of .h output    */
                     10: #define        CONFIGIN        "Configuration"         /* name of input file   */
                     11: 
                     12: FILE   *confc;
                     13: FILE   *confh;
                     14: 
                     15: char   *dbstr;
                     16: extern char *malloc();
                     17: int    ndevs = 0;
                     18: int    currname = -1;
                     19: int    currtname = -1;
                     20: int    currdname = -1;
                     21: int    brkcount = 0;
                     22: 
                     23: struct syment  {                       /* symbol table                 */
                     24:        char    *symname;
                     25:        int     symoccurs;
                     26:        } symtab[250];
                     27: 
                     28: int    nsym = 0;
                     29: int    lookup();
                     30: int    linectr = 1;
                     31: char   *doing = "device type declaration";
                     32: char   *s;
                     33: struct dvtype {
                     34:        char            *dvname;        /* device name (not used in types)*/
                     35:        char            *dvtname;       /* type name                    */
                     36:        int             dvtnum;         /* symbol table index of type   */
                     37:        char            *dvdevice;      /* device name                  */
                     38:        int             dvcsr;          /* Control Status Register addr */
                     39:        int             dvivec;         /* input interrupt vector       */
                     40:        int             dvovec;         /* Output interrupt vector      */
                     41:        char            dviint[20];     /* input interrupt routine      */
                     42:        char            dvoint[20];     /* output interrupt routine     */
                     43:        char            dvinit[20];     /* init routine name            */
                     44:        char            dvopen[20];     /* open routine name            */
                     45:        char            dvclose[20];    /* close routine name           */
                     46:        char            dvread[20];     /* read routine name            */
                     47:        char            dvwrite[20];    /* write routine name           */
                     48:        char            dvcntl[20];     /* control routine name         */
                     49:        char            dvseek[20];     /* seek routine name            */
                     50:        char            dvgetc[20];     /* getc routine name            */
                     51:        char            dvputc[20];     /* putc routine name            */
                     52:        int             dvminor;        /* device number 0,1,...        */
                     53:        struct dvtype   *dvnext;        /* next node on the list        */
                     54:        };
                     55: typedef        struct  dvtype  *dvptr;
                     56:        dvptr   ftypes = NIL;           /* linked list of device types  */
                     57:        dvptr   devs = NIL;             /* linked list of device decls. */
                     58:        dvptr   lastdv = NIL;
                     59:        dvptr   currtype = NIL;
                     60: 
                     61: char   *ftout[] = 
1.1.1.2 ! root       62:               {"struct\tdevsw\t{\t\t\t/* device table entry */\n",
1.1       root       63:                "\tint\tdvnum;\n",
                     64:                "\tint\t(*dvinit)();\n",
                     65:                "\tint\t(*dvopen)();\n",
                     66:                "\tint\t(*dvclose)();\n",
                     67:                "\tint\t(*dvread)();\n",
                     68:                "\tint\t(*dvwrite)();\n",
                     69:                "\tint\t(*dvseek)();\n",
                     70:                "\tint\t(*dvgetc)();\n",
                     71:                "\tint\t(*dvputc)();\n",
                     72:                "\tint\t(*dvcntl)();\n",
                     73:                "\tint\tdvcsr;\n",
                     74:                "\tint\tdvivec;\n",
                     75:                "\tint\tdvovec;\n",
                     76:                "\tint\t(*dviint)();\n",
                     77:                "\tint\t(*dvoint)();\n",
                     78:                "\tchar\t*dvioblk;\n",
                     79:                "\tint\tdvminor;\n",
                     80:                "\t};\n\n",
                     81:                "extern\tstruct\tdevsw devtab[];",
1.1.1.2 ! root       82:                "\t\t/* one entry per device */\n\n",
1.1       root       83:                NULL};
                     84: %}
                     85: %%
                     86: config.input   :       devicetypes devicedescriptors
                     87:                ;
                     88: devicetypes    :       ftypes DEFBRK
                     89:                                        {doing = "device definitions";}
                     90:                ;
                     91: ftypes         :       /**/
                     92:                |       ftypes ftype
                     93:                ;
                     94: ftype          :       tname device.list
                     95:                ;
                     96: device.list    :       devheader attribute.list
                     97:                |       device.list devheader attribute.list
                     98:                ;
                     99: devheader      :       ON id
                    100:                                        {mktype($2);}
                    101:                ;
                    102: tname          :       id COLON
                    103:                                        {$$ = currtname = cktname($1);}
                    104:                ;
                    105: id             :       IDENT
                    106:                                        {$$ = currname =
                    107:                                         lookup(yytext,yyleng);
                    108:                                        }
                    109:                ;
                    110: attribute.list :       /**/
                    111:                |       attribute.list attribute
                    112:                ;
                    113: attribute      :       CSR number
                    114:                                        {newattr(CSR,$2);}
                    115:                |       IVEC number
                    116:                                        {newattr(IVEC,$2);}
                    117:                |       OVEC number
                    118:                                        {newattr(OVEC,$2);}
                    119:                |       IINT id
                    120:                                        {newattr(IINT,$2);}
                    121:                |       OINT id
                    122:                                        {newattr(OINT,$2);}
                    123:                |       OPEN id
                    124:                                        {newattr(OPEN,$2);}
                    125:                |       CLOSE id
                    126:                                        {newattr(CLOSE,$2);}
                    127:                |       INIT id
                    128:                                        {newattr(INIT,$2);}
                    129:                |       GETC id
                    130:                                        {newattr(GETC,$2);}
                    131:                |       PUTC id
                    132:                                        {newattr(PUTC,$2);}
                    133:                |       READ id
                    134:                                        {newattr(READ,$2);}
                    135:                |       WRITE id
                    136:                                        {newattr(WRITE,$2);}
                    137:                |       SEEK id
                    138:                                        {newattr(SEEK,$2);}
                    139:                |       CNTL id
                    140:                                        {newattr(CNTL,$2);}
                    141:                ;
                    142: number         :       INTEGER
                    143:                                        /* Assume all input is octal */
                    144:                                        /* for now; distinction is   */
                    145:                                        /* made in lexical routines  */
                    146:                                        /* just in case of change    */
                    147: 
                    148:                                        {$$ = otoi(yytext,yyleng);}
                    149:                |       OCTAL
                    150:                                        {$$ = otoi(yytext,yyleng);}
                    151:                ;
                    152: devicedescriptors      :       /**/
                    153:                |       devicedescriptors descriptor
                    154:                ;
                    155: descriptor     :       fspec attribute.list
                    156:                ;
                    157: fspec          :       dname IS id optional.on
                    158:                                        {mkdev($1,$3,$4);}
                    159:                ;
                    160: dname          :       id
                    161:                                        {$$ = currdname = ckdname($1);}
                    162:                ;
                    163: optional.on    :       /**/
                    164:                                        {$$ = 0;}
                    165:                |       ON id
                    166:                                        {$$ = $2;}
                    167:                ;
                    168: %%
                    169: #include "lex.yy.c"
                    170: main(argc, argv)
                    171:        int     argc;
                    172:        char    *argv[];
                    173: {
                    174:        int     n, i, j, l, fcount;
                    175:        dvptr   s;
                    176:        int     verbose = 0;
                    177:        char    *p;
                    178:        char    c;
                    179: 
                    180:        if (argc>1 && (strcmp("-v",argv[1])==0)) {
                    181:                argc--;
                    182:                argv++;
                    183:                verbose++;
                    184:        }
                    185:        if (argc>2) {
                    186:                fprintf(stderr,"use: config [-v] [file]\n");
                    187:                exit(1);
                    188:        }
                    189:        if (verbose)
                    190:                printf("Opening input file...\n");
                    191:        if (argc == 2) {
                    192:                if (freopen(argv[1], "r", stdin) == NULL) {
                    193:                        fprintf(stderr,"Can't open %s\n",argv[1]);
                    194:                        exit(1);
                    195:                }
                    196:        } else {        /* try to open Configuration file */
                    197:                if (freopen(CONFIGIN, "r", stdin) == NULL) {
                    198:                        fprintf(stderr,"Can't open %s\n", CONFIGIN);
                    199:                        exit(1);
                    200:                }
                    201:        }
                    202: 
                    203:        /* Parse the Configuration file */
                    204: 
                    205:        if (verbose)
                    206:                printf("Parsing configuration specs...\n");
                    207:        if ((n=yyparse()) != 0)
                    208:                exit(n);
                    209: 
                    210:        /* write config.h and config.c */
                    211: 
                    212:        if (verbose)
                    213:                printf("Opening output files...\n");
                    214:        if ( (confc=fopen(CONFIGC,"w") ) == NULL) {
                    215:                fprintf(stderr, "Can't write on %s\n", CONFIGC);
                    216:                exit(1);
                    217:        }
                    218: 
                    219:        if ( (confh=fopen(CONFIGH,"w") ) == NULL) {
                    220:                fprintf(stderr, "Can't write on %s\n", CONFIGH);
                    221:                exit(1);
                    222:        }
                    223:        fprintf(confh,
                    224:                "/* conf.h (GENERATED FILE; DO NOT EDIT) */\n");
                    225:        fprintf(confc,
                    226:                "/* conf.c (GENERATED FILE; DO NOT EDIT) */\n");
1.1.1.2 ! root      227:        fprintf(confc, "\n#include \"%s\"\n", CONFIGH);
1.1       root      228:        fprintf(confh, "\n#define\tNULLPTR\t(char *)0\n");
                    229: 
                    230: 
                    231:        if (verbose)
                    232:                printf("Writing output...\n");
                    233:        fprintf(confh,"\n/* Device table declarations */\n");
                    234:        for (i=0 ; (p=ftout[i])!=NULL ; i++)
                    235:                fprintf(confh, "%s", p);
1.1.1.2 ! root      236: 
1.1       root      237:        /* write device declarations and definitions; count type refs. */
                    238: 
                    239:        fprintf(confh, "\n/* Device name definitions */\n\n");
                    240:        for (i=0,s=devs; s!=NIL ; s=s->dvnext,i++) {
                    241:                fprintf(confh, "#define\t%-12s%d\t\t\t/* type %-8s */\n",
                    242:                        s->dvname, i, s->dvtname);
                    243:                s->dvminor = symtab[s->dvtnum].symoccurs++;
                    244:        }
                    245: 
                    246:        /* write count of device types */
                    247: 
                    248:        fprintf(confh,"\n/* Control block sizes */\n\n");
                    249:        for (i=0 ; i<nsym ; i++)
                    250:                if (symtab[i].symoccurs > 0) {
                    251:                        fprintf(confh, "#define\tN%s\t%d\n",
                    252:                                symtab[i].symname, symtab[i].symoccurs);
                    253:                }
                    254:        if (ndevs > 0)
                    255:                fprintf(confh, "\n#define\tNDEVS\t%d\n\n", ndevs);
                    256: 
                    257:        /* empty symbol table, collect, and write names of all I/O routines */
                    258: 
                    259:        nsym = 0;
                    260:        for (s=devs; s!=NIL ; s=s->dvnext) {
                    261:                lookup(s->dvinit,strlen(s->dvinit));
                    262:                lookup(s->dvopen,strlen(s->dvopen));
                    263:                lookup(s->dvclose,strlen(s->dvclose));
                    264:                lookup(s->dvread,strlen(s->dvread));
                    265:                lookup(s->dvwrite,strlen(s->dvwrite));
                    266:                lookup(s->dvseek,strlen(s->dvseek));
                    267:                lookup(s->dvcntl,strlen(s->dvcntl));
                    268:                lookup(s->dvgetc,strlen(s->dvgetc));
                    269:                lookup(s->dvputc,strlen(s->dvputc));
                    270:                lookup(s->dviint,strlen(s->dviint));
                    271:                lookup(s->dvoint,strlen(s->dvoint));
                    272:                
                    273:        }
                    274:        fprintf(confh,
                    275:                "/* Declarations of I/O routines referenced */\n\n");
                    276:        for (i=0 ; i<nsym ; i++)
                    277:                fprintf(confh, "extern\tint\t%s();\n", symtab[i].symname);
                    278: 
                    279: 
                    280:        /* produce devtab (giant I/O switch table) */
                    281: 
                    282:        fprintf(confc, "\n/* device independent I/O switch */\n\n");
1.1.1.2 ! root      283:        if (ndevs > 0)
1.1       root      284:                fprintf(confc, "struct\tdevsw\tdevtab[NDEVS] = {\n");
                    285:        for (fcount=0,s=devs ; s!=NIL ; s=s->dvnext,fcount++) {
1.1.1.2 ! root      286:                fprintf(confc, "\n/*  %s */\n", s->dvname, s->dvtname);
        !           287:                fprintf(confc, "%d,\n", fcount);
1.1       root      288:                fprintf(confc, "%s, %s, %s,\n",
                    289:                        s->dvinit, s->dvopen, s->dvclose);
                    290:                fprintf(confc, "%s, %s, %s,\n",
                    291:                        s->dvread, s->dvwrite, s->dvseek);
                    292:                fprintf(confc, "%s, %s, %s,\n",
                    293:                        s->dvgetc, s->dvputc, s->dvcntl);
                    294:                fprintf(confc, "0%06o, 0%03o, 0%03o,\n",
                    295:                        s->dvcsr, s->dvivec, s->dvovec);
                    296:                fprintf(confc, "%s, %s, NULLPTR, %d",
                    297:                        s->dviint, s->dvoint, s->dvminor);
                    298:                if ( s->dvnext != NIL )
                    299:                        fprintf(confc, ",\n");
                    300:                else
                    301:                        fprintf(confc, "\n\t};");
                    302:        }
                    303: 
                    304:        /* Copy definitions to output */
                    305: 
                    306:        if (brkcount == 2 && verbose)
                    307:                printf("Copying definitions to %s...\n", CONFIGH);
                    308:        if (brkcount == 2 )
                    309:                while ( (c=input()) != 0)       /* lex input routine */
                    310:                        putc(c, confh);
                    311: 
                    312:        /* guarantee conf.c written later than conf.c for make */
                    313: 
                    314:        fclose(confh);
                    315:        fprintf(confc, "\n");
                    316:        fclose(confc);
                    317: 
                    318:        /* finish up and write report for user if requested */
                    319: 
                    320:        if (verbose) {
                    321:            printf("\nConfiguration complete. Number of devs=%d:\n\n",ndevs);
                    322:            for (s=devs; s!=NIL ; s=s->dvnext)
                    323:              printf(
                    324:                "Device %s (on %s) csr=0%-7o, ivec=0%-3o, ovec=0%-3o, minor=%d\n",
                    325:                s->dvname, s->dvdevice, s->dvcsr, s->dvivec, s->dvovec,
                    326:                s->dvminor);
                    327:        }
                    328:        
                    329: 
                    330: }
                    331: 
                    332: 
                    333: yyerror(s)
                    334:        char *s;
                    335: {
                    336:        fprintf(stderr,"Syntax error in %s on line %d\n",
                    337:                doing,linectr);
                    338: }
                    339: 
                    340: 
                    341: /*  lookup  --  lookup a name in the symbol table; return position */
                    342: 
                    343: lookup(str,len)
                    344:        char    *str;
                    345:        int     len;
                    346: {
                    347:        int     i;
                    348:        char    *s;
                    349: 
                    350:        if (len >= 20) {
                    351:                len = 19;
                    352:                fprintf(stderr,"warning: name %s truncated\n",str);
                    353:                }
                    354:        s = malloc(len+1);
                    355:        strncpy(s,str,len);
                    356:        s[len] = '\000';
                    357:        for (i=0 ; i<nsym ; i++)
                    358:                if (strcmp(s,symtab[i].symname) == 0){
                    359:                        return(i);
                    360:                }
                    361:        symtab[nsym].symname = s;
                    362:        symtab[nsym].symoccurs = 0;
                    363:        return(nsym++);
                    364: }
                    365: 
                    366: atoi(str,len)
                    367:        char *str;
                    368:        int len;
                    369: {
                    370:        int i;
                    371:        char c;
                    372: 
                    373:        for (i=0; len > 0 ; len--) {
                    374:                c = *str++;
                    375:                i = 10*i + (c - '0');
                    376:                }
                    377: }
                    378: otoi(str,len)
                    379:        char *str;
                    380:        int len;
                    381: {
                    382:        int i;
                    383:        char c;
                    384: 
                    385:        for (i=0; len > 0 ; len--) {
                    386:                c = *str++;
                    387:                if (c > '7')
                    388:                        fprintf(stderr,"invalid octal digit on line %d\n",
                    389:                                linectr);
                    390:                else
                    391:                        i = 8*i + (c - '0');
                    392:                }
                    393: }
                    394: 
                    395: /* newattr -- add a new attribute spec to current type/device description      */
                    396: 
                    397: newattr(tok,val)
                    398:        int     tok;                    /* token type (attribute type)  */
                    399:        int     val;                    /* symbol number of value       */
                    400: {
                    401:        char    *c;
                    402:        dvptr   s;
                    403: 
                    404:        if (devs == NIL)                /* doing types                  */
                    405:                s = currtype;
                    406:        else
                    407:                s = lastdv;
                    408:        if (val>=0 && val<nsym) {
                    409:                c = symtab[val].symname;
                    410:                if (strlen(c) > 20 ) {
                    411:                        fprintf(stderr,"Internal overflow\n");
                    412:                        exit(1);
                    413:                }
                    414:        } else
                    415:                c = NULL;
                    416: 
                    417:        switch (tok) {
                    418: 
                    419:        case CSR:       s->dvcsr = val;
                    420:                        break;
                    421:        case IVEC:      s->dvivec = val;
                    422:                        break;
                    423:        case OVEC:      s->dvovec = val;
                    424:                        break;
                    425:        case IINT:      strcpy(s->dviint,c);
                    426:                        break;
                    427:        case OINT:      strcpy(s->dvoint,c);
                    428:                        break;
                    429:        case READ:      strcpy(s->dvread,c);
                    430:                        break;
                    431:        case WRITE:     strcpy(s->dvwrite,c);
                    432:                        break;
                    433:        case GETC:      strcpy(s->dvgetc,c);
                    434:                        break;
                    435:        case PUTC:      strcpy(s->dvputc,c);
                    436:                        break;
                    437:        case OPEN:      strcpy(s->dvopen,c);
                    438:                        break;
                    439:        case CLOSE:     strcpy(s->dvclose,c);
                    440:                        break;
                    441:        case INIT:      strcpy(s->dvinit,c);
                    442:                        break;
                    443:        case SEEK:      strcpy(s->dvseek,c);
                    444:                        break;
                    445:        case CNTL:      strcpy(s->dvcntl,c);
                    446:                        break;
                    447:        default:        fprintf(stderr, "Internal error 1\n");
                    448:        }
                    449: }
                    450: 
                    451: /* cktname  --  check type name for duplicates */
                    452: 
                    453: cktname(symid)
                    454:        int symid;
                    455: {
                    456:        dvptr   s;
                    457: extern dvptr   ftypes;
                    458:        char    *name;
                    459: 
                    460:        name = symtab[symid].symname;
                    461:        for (s=ftypes; s!=NIL ; s=s->dvnext) {
                    462:                if (s->dvtname == name) {
                    463:                        fprintf(stderr,"Duplicate type name %s on line %d\n",
                    464:                                name,linectr);
                    465:                        exit(1);
                    466:                        }
                    467:                }
                    468:        return(symid);
                    469: }
                    470: 
                    471: /* mktype  --  make a node in the type list and initialize to defaults */
                    472: 
                    473: mktype(deviceid)
                    474:        int deviceid;
                    475: {
                    476:        dvptr   s,p;
                    477:        char    *tn,*dn;
                    478: 
                    479:        p = NIL;
                    480:        tn = symtab[currtname].symname;
                    481:        dn = symtab[deviceid].symname;
                    482:        for (s = ftypes; s!=NIL ; s=s->dvnext) {
                    483:                if (s->dvtname == tn && s->dvdevice==dn) {
                    484:                   fprintf(stderr,
                    485:                     "Duplicate device %s for type %s on line %d\n",
                    486:                     dn, tn, linectr);
                    487:                   exit(1);
                    488:                }
                    489:                p = s;
                    490:        }
                    491:        currtype = s = (dvptr) malloc( sizeof(struct dvtype));
                    492:        if (ftypes != NIL) {
                    493:                p->dvnext = s;
                    494:        }
                    495:        else {
                    496:                ftypes = s;
                    497:        }
                    498:        initattr(s, currtname, deviceid);
                    499: }
                    500: 
                    501: /* initialize attributes in a type declaration node to typename...     */
                    502: 
                    503: initattr(fstr, tnum, deviceid)
                    504:        dvptr   fstr;
                    505:        int     tnum;
                    506:        int     deviceid;
                    507: {
                    508:        char    *typnam;
                    509: 
                    510:        typnam = symtab[tnum].symname;
                    511:        fstr->dvname = NULL;
                    512:        fstr->dvtname = typnam;
                    513:        fstr->dvtnum = tnum;
                    514:        fstr->dvdevice = symtab[deviceid].symname;
                    515:        fstr->dvcsr = 0;
                    516:        fstr->dvivec = 0;
                    517:        fstr->dvovec = 0;
                    518:        strcpy(fstr->dviint,typnam);
                    519:        strcat(fstr->dviint,"iin");
                    520:        strcpy(fstr->dvoint,typnam);
                    521:        strcat(fstr->dvoint,"oin");
                    522:        strcpy(fstr->dvinit,typnam);
                    523:        strcat(fstr->dvinit,"init");
                    524:        strcpy(fstr->dvopen,typnam);
                    525:        strcat(fstr->dvopen,"open");
                    526:        strcpy(fstr->dvclose,typnam);
                    527:        strcat(fstr->dvclose,"close");
                    528:        strcpy(fstr->dvread,typnam);
                    529:        strcat(fstr->dvread,"read");
                    530:        strcpy(fstr->dvwrite,typnam);
                    531:        strcat(fstr->dvwrite,"write");
                    532:        strcpy(fstr->dvcntl,typnam);
                    533:        strcat(fstr->dvcntl,"control");
                    534:        strcpy(fstr->dvseek,typnam);
                    535:        strcat(fstr->dvseek,"seek");
                    536:        strcpy(fstr->dvgetc,typnam);
                    537:        strcat(fstr->dvgetc,"getc");
                    538:        strcpy(fstr->dvputc,typnam);
                    539:        strcat(fstr->dvputc,"putc");
                    540:        fstr->dvminor = 0;
                    541: }
                    542: 
                    543: /* mkdev  --  make a node on the device list */
                    544: 
                    545: mkdev(nameid, typid, deviceid)
                    546:        int     nameid, typid, deviceid;
                    547: {
                    548:        dvptr   s;
                    549:        char    *devn,*tn,*dn;
                    550:        int     found;
                    551: 
                    552:        s = (dvptr) malloc(sizeof(struct dvtype));
                    553:        s->dvnext = NIL;
                    554:        if (devs == NIL) {
                    555:                devs = s;
                    556:                lastdv = s;
                    557:        } else {
                    558:                lastdv->dvnext = s;
                    559:                lastdv = s;
                    560:        }
                    561:        ndevs++;
                    562:        tn = symtab[typid].symname;
                    563:        devn = symtab[nameid].symname;
                    564:        if (deviceid >= 0)
                    565:                dn = symtab[deviceid].symname;
                    566:        else
                    567:                dn = NULL;
                    568:        found = 0;
                    569:        for (s=ftypes ; s != NULL ; s=s->dvnext)
                    570:                if (s->dvtname == tn && (dn==NULL || s->dvdevice==dn)) {
                    571:                        strdup(lastdv,s,sizeof(struct dvtype));
                    572:                        found=1;
                    573:                        break;
                    574:                }
                    575:        if (found==0) {
                    576:                fprintf(stderr,
                    577:                  "Bad type or device name in declaration of %s on line %d\n",
                    578:                  devn, linectr);
                    579:                exit(1);
                    580:        }
                    581:        lastdv->dvnext = NIL;
                    582:        lastdv->dvname = devn;
                    583: }
                    584: 
                    585: 
                    586: /* chdname  -- check for duplicate device name */
                    587: 
                    588: ckdname(devid)
                    589:        int devid;
                    590: {
                    591:        dvptr   s;
                    592: extern dvptr   devs;
                    593:        char    *name;
                    594: 
                    595:        name = symtab[devid].symname;
                    596:        for (s=devs; s!=NIL ; s=s->dvnext) {
                    597:                if (s->dvname == name) {
                    598:                        fprintf(stderr,"Duplicate device name %s on line %d\n",
                    599:                                name,linectr);
                    600:                        exit(1);
                    601:                        }
                    602:                }
                    603:        return(devid);
                    604: }
                    605: 
                    606: strdup(tostr,fromstr,len)
                    607:        char    *tostr, *fromstr;
                    608:        int     len;
                    609: {
                    610:        for( ; len > 0 ; len--)
                    611:                *tostr++ = *fromstr++;
                    612: }

unix.superglobalmegacorp.com

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