Annotation of qemu/roms/seabios/tools/kconfig/conf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2002 Roman Zippel <[email protected]>
        !             3:  * Released under the terms of the GNU GPL v2.0.
        !             4:  */
        !             5: 
        !             6: #include <locale.h>
        !             7: #include <ctype.h>
        !             8: #include <stdio.h>
        !             9: #include <stdlib.h>
        !            10: #include <string.h>
        !            11: #include <time.h>
        !            12: #include <unistd.h>
        !            13: #include <getopt.h>
        !            14: #include <sys/stat.h>
        !            15: #include <sys/time.h>
        !            16: 
        !            17: #define LKC_DIRECT_LINK
        !            18: #include "lkc.h"
        !            19: 
        !            20: static void conf(struct menu *menu);
        !            21: static void check_conf(struct menu *menu);
        !            22: 
        !            23: enum input_mode {
        !            24:        oldaskconfig,
        !            25:        silentoldconfig,
        !            26:        oldconfig,
        !            27:        allnoconfig,
        !            28:        allyesconfig,
        !            29:        allmodconfig,
        !            30:        alldefconfig,
        !            31:        randconfig,
        !            32:        defconfig,
        !            33:        savedefconfig,
        !            34:        listnewconfig,
        !            35:        oldnoconfig,
        !            36: } input_mode = oldaskconfig;
        !            37: 
        !            38: char *defconfig_file;
        !            39: 
        !            40: static int indent = 1;
        !            41: static int valid_stdin = 1;
        !            42: static int sync_kconfig;
        !            43: static int conf_cnt;
        !            44: static char line[128];
        !            45: static struct menu *rootEntry;
        !            46: 
        !            47: static void print_help(struct menu *menu)
        !            48: {
        !            49:        struct gstr help = str_new();
        !            50: 
        !            51:        menu_get_ext_help(menu, &help);
        !            52: 
        !            53:        printf("\n%s\n", str_get(&help));
        !            54:        str_free(&help);
        !            55: }
        !            56: 
        !            57: static void strip(char *str)
        !            58: {
        !            59:        char *p = str;
        !            60:        int l;
        !            61: 
        !            62:        while ((isspace(*p)))
        !            63:                p++;
        !            64:        l = strlen(p);
        !            65:        if (p != str)
        !            66:                memmove(str, p, l + 1);
        !            67:        if (!l)
        !            68:                return;
        !            69:        p = str + l - 1;
        !            70:        while ((isspace(*p)))
        !            71:                *p-- = 0;
        !            72: }
        !            73: 
        !            74: static void check_stdin(void)
        !            75: {
        !            76:        if (!valid_stdin) {
        !            77:                printf(_("aborted!\n\n"));
        !            78:                printf(_("Console input/output is redirected. "));
        !            79:                printf(_("Run 'make oldconfig' to update configuration.\n\n"));
        !            80:                exit(1);
        !            81:        }
        !            82: }
        !            83: 
        !            84: static int conf_askvalue(struct symbol *sym, const char *def)
        !            85: {
        !            86:        enum symbol_type type = sym_get_type(sym);
        !            87: 
        !            88:        if (!sym_has_value(sym))
        !            89:                printf(_("(NEW) "));
        !            90: 
        !            91:        line[0] = '\n';
        !            92:        line[1] = 0;
        !            93: 
        !            94:        if (!sym_is_changable(sym)) {
        !            95:                printf("%s\n", def);
        !            96:                line[0] = '\n';
        !            97:                line[1] = 0;
        !            98:                return 0;
        !            99:        }
        !           100: 
        !           101:        switch (input_mode) {
        !           102:        case oldconfig:
        !           103:        case silentoldconfig:
        !           104:                if (sym_has_value(sym)) {
        !           105:                        printf("%s\n", def);
        !           106:                        return 0;
        !           107:                }
        !           108:                check_stdin();
        !           109:        case oldaskconfig:
        !           110:                fflush(stdout);
        !           111:                xfgets(line, 128, stdin);
        !           112:                return 1;
        !           113:        default:
        !           114:                break;
        !           115:        }
        !           116: 
        !           117:        switch (type) {
        !           118:        case S_INT:
        !           119:        case S_HEX:
        !           120:        case S_STRING:
        !           121:                printf("%s\n", def);
        !           122:                return 1;
        !           123:        default:
        !           124:                ;
        !           125:        }
        !           126:        printf("%s", line);
        !           127:        return 1;
        !           128: }
        !           129: 
        !           130: static int conf_string(struct menu *menu)
        !           131: {
        !           132:        struct symbol *sym = menu->sym;
        !           133:        const char *def;
        !           134: 
        !           135:        while (1) {
        !           136:                printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
        !           137:                printf("(%s) ", sym->name);
        !           138:                def = sym_get_string_value(sym);
        !           139:                if (sym_get_string_value(sym))
        !           140:                        printf("[%s] ", def);
        !           141:                if (!conf_askvalue(sym, def))
        !           142:                        return 0;
        !           143:                switch (line[0]) {
        !           144:                case '\n':
        !           145:                        break;
        !           146:                case '?':
        !           147:                        /* print help */
        !           148:                        if (line[1] == '\n') {
        !           149:                                print_help(menu);
        !           150:                                def = NULL;
        !           151:                                break;
        !           152:                        }
        !           153:                default:
        !           154:                        line[strlen(line)-1] = 0;
        !           155:                        def = line;
        !           156:                }
        !           157:                if (def && sym_set_string_value(sym, def))
        !           158:                        return 0;
        !           159:        }
        !           160: }
        !           161: 
        !           162: static int conf_sym(struct menu *menu)
        !           163: {
        !           164:        struct symbol *sym = menu->sym;
        !           165:        tristate oldval, newval;
        !           166: 
        !           167:        while (1) {
        !           168:                printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
        !           169:                if (sym->name)
        !           170:                        printf("(%s) ", sym->name);
        !           171:                putchar('[');
        !           172:                oldval = sym_get_tristate_value(sym);
        !           173:                switch (oldval) {
        !           174:                case no:
        !           175:                        putchar('N');
        !           176:                        break;
        !           177:                case mod:
        !           178:                        putchar('M');
        !           179:                        break;
        !           180:                case yes:
        !           181:                        putchar('Y');
        !           182:                        break;
        !           183:                }
        !           184:                if (oldval != no && sym_tristate_within_range(sym, no))
        !           185:                        printf("/n");
        !           186:                if (oldval != mod && sym_tristate_within_range(sym, mod))
        !           187:                        printf("/m");
        !           188:                if (oldval != yes && sym_tristate_within_range(sym, yes))
        !           189:                        printf("/y");
        !           190:                if (menu_has_help(menu))
        !           191:                        printf("/?");
        !           192:                printf("] ");
        !           193:                if (!conf_askvalue(sym, sym_get_string_value(sym)))
        !           194:                        return 0;
        !           195:                strip(line);
        !           196: 
        !           197:                switch (line[0]) {
        !           198:                case 'n':
        !           199:                case 'N':
        !           200:                        newval = no;
        !           201:                        if (!line[1] || !strcmp(&line[1], "o"))
        !           202:                                break;
        !           203:                        continue;
        !           204:                case 'm':
        !           205:                case 'M':
        !           206:                        newval = mod;
        !           207:                        if (!line[1])
        !           208:                                break;
        !           209:                        continue;
        !           210:                case 'y':
        !           211:                case 'Y':
        !           212:                        newval = yes;
        !           213:                        if (!line[1] || !strcmp(&line[1], "es"))
        !           214:                                break;
        !           215:                        continue;
        !           216:                case 0:
        !           217:                        newval = oldval;
        !           218:                        break;
        !           219:                case '?':
        !           220:                        goto help;
        !           221:                default:
        !           222:                        continue;
        !           223:                }
        !           224:                if (sym_set_tristate_value(sym, newval))
        !           225:                        return 0;
        !           226: help:
        !           227:                print_help(menu);
        !           228:        }
        !           229: }
        !           230: 
        !           231: static int conf_choice(struct menu *menu)
        !           232: {
        !           233:        struct symbol *sym, *def_sym;
        !           234:        struct menu *child;
        !           235:        bool is_new;
        !           236: 
        !           237:        sym = menu->sym;
        !           238:        is_new = !sym_has_value(sym);
        !           239:        if (sym_is_changable(sym)) {
        !           240:                conf_sym(menu);
        !           241:                sym_calc_value(sym);
        !           242:                switch (sym_get_tristate_value(sym)) {
        !           243:                case no:
        !           244:                        return 1;
        !           245:                case mod:
        !           246:                        return 0;
        !           247:                case yes:
        !           248:                        break;
        !           249:                }
        !           250:        } else {
        !           251:                switch (sym_get_tristate_value(sym)) {
        !           252:                case no:
        !           253:                        return 1;
        !           254:                case mod:
        !           255:                        printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
        !           256:                        return 0;
        !           257:                case yes:
        !           258:                        break;
        !           259:                }
        !           260:        }
        !           261: 
        !           262:        while (1) {
        !           263:                int cnt, def;
        !           264: 
        !           265:                printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
        !           266:                def_sym = sym_get_choice_value(sym);
        !           267:                cnt = def = 0;
        !           268:                line[0] = 0;
        !           269:                for (child = menu->list; child; child = child->next) {
        !           270:                        if (!menu_is_visible(child))
        !           271:                                continue;
        !           272:                        if (!child->sym) {
        !           273:                                printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
        !           274:                                continue;
        !           275:                        }
        !           276:                        cnt++;
        !           277:                        if (child->sym == def_sym) {
        !           278:                                def = cnt;
        !           279:                                printf("%*c", indent, '>');
        !           280:                        } else
        !           281:                                printf("%*c", indent, ' ');
        !           282:                        printf(" %d. %s", cnt, _(menu_get_prompt(child)));
        !           283:                        if (child->sym->name)
        !           284:                                printf(" (%s)", child->sym->name);
        !           285:                        if (!sym_has_value(child->sym))
        !           286:                                printf(_(" (NEW)"));
        !           287:                        printf("\n");
        !           288:                }
        !           289:                printf(_("%*schoice"), indent - 1, "");
        !           290:                if (cnt == 1) {
        !           291:                        printf("[1]: 1\n");
        !           292:                        goto conf_childs;
        !           293:                }
        !           294:                printf("[1-%d", cnt);
        !           295:                if (menu_has_help(menu))
        !           296:                        printf("?");
        !           297:                printf("]: ");
        !           298:                switch (input_mode) {
        !           299:                case oldconfig:
        !           300:                case silentoldconfig:
        !           301:                        if (!is_new) {
        !           302:                                cnt = def;
        !           303:                                printf("%d\n", cnt);
        !           304:                                break;
        !           305:                        }
        !           306:                        check_stdin();
        !           307:                case oldaskconfig:
        !           308:                        fflush(stdout);
        !           309:                        xfgets(line, 128, stdin);
        !           310:                        strip(line);
        !           311:                        if (line[0] == '?') {
        !           312:                                print_help(menu);
        !           313:                                continue;
        !           314:                        }
        !           315:                        if (!line[0])
        !           316:                                cnt = def;
        !           317:                        else if (isdigit(line[0]))
        !           318:                                cnt = atoi(line);
        !           319:                        else
        !           320:                                continue;
        !           321:                        break;
        !           322:                default:
        !           323:                        break;
        !           324:                }
        !           325: 
        !           326:        conf_childs:
        !           327:                for (child = menu->list; child; child = child->next) {
        !           328:                        if (!child->sym || !menu_is_visible(child))
        !           329:                                continue;
        !           330:                        if (!--cnt)
        !           331:                                break;
        !           332:                }
        !           333:                if (!child)
        !           334:                        continue;
        !           335:                if (line[strlen(line) - 1] == '?') {
        !           336:                        print_help(child);
        !           337:                        continue;
        !           338:                }
        !           339:                sym_set_choice_value(sym, child->sym);
        !           340:                for (child = child->list; child; child = child->next) {
        !           341:                        indent += 2;
        !           342:                        conf(child);
        !           343:                        indent -= 2;
        !           344:                }
        !           345:                return 1;
        !           346:        }
        !           347: }
        !           348: 
        !           349: static void conf(struct menu *menu)
        !           350: {
        !           351:        struct symbol *sym;
        !           352:        struct property *prop;
        !           353:        struct menu *child;
        !           354: 
        !           355:        if (!menu_is_visible(menu))
        !           356:                return;
        !           357: 
        !           358:        sym = menu->sym;
        !           359:        prop = menu->prompt;
        !           360:        if (prop) {
        !           361:                const char *prompt;
        !           362: 
        !           363:                switch (prop->type) {
        !           364:                case P_MENU:
        !           365:                        if ((input_mode == silentoldconfig ||
        !           366:                             input_mode == listnewconfig ||
        !           367:                             input_mode == oldnoconfig) &&
        !           368:                            rootEntry != menu) {
        !           369:                                check_conf(menu);
        !           370:                                return;
        !           371:                        }
        !           372:                case P_COMMENT:
        !           373:                        prompt = menu_get_prompt(menu);
        !           374:                        if (prompt)
        !           375:                                printf("%*c\n%*c %s\n%*c\n",
        !           376:                                        indent, '*',
        !           377:                                        indent, '*', _(prompt),
        !           378:                                        indent, '*');
        !           379:                default:
        !           380:                        ;
        !           381:                }
        !           382:        }
        !           383: 
        !           384:        if (!sym)
        !           385:                goto conf_childs;
        !           386: 
        !           387:        if (sym_is_choice(sym)) {
        !           388:                conf_choice(menu);
        !           389:                if (sym->curr.tri != mod)
        !           390:                        return;
        !           391:                goto conf_childs;
        !           392:        }
        !           393: 
        !           394:        switch (sym->type) {
        !           395:        case S_INT:
        !           396:        case S_HEX:
        !           397:        case S_STRING:
        !           398:                conf_string(menu);
        !           399:                break;
        !           400:        default:
        !           401:                conf_sym(menu);
        !           402:                break;
        !           403:        }
        !           404: 
        !           405: conf_childs:
        !           406:        if (sym)
        !           407:                indent += 2;
        !           408:        for (child = menu->list; child; child = child->next)
        !           409:                conf(child);
        !           410:        if (sym)
        !           411:                indent -= 2;
        !           412: }
        !           413: 
        !           414: static void check_conf(struct menu *menu)
        !           415: {
        !           416:        struct symbol *sym;
        !           417:        struct menu *child;
        !           418: 
        !           419:        if (!menu_is_visible(menu))
        !           420:                return;
        !           421: 
        !           422:        sym = menu->sym;
        !           423:        if (sym && !sym_has_value(sym)) {
        !           424:                if (sym_is_changable(sym) ||
        !           425:                    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
        !           426:                        if (input_mode == listnewconfig) {
        !           427:                                if (sym->name && !sym_is_choice_value(sym)) {
        !           428:                                        printf("%s%s\n", CONFIG_, sym->name);
        !           429:                                }
        !           430:                        } else if (input_mode != oldnoconfig) {
        !           431:                                if (!conf_cnt++)
        !           432:                                        printf(_("*\n* Restart config...\n*\n"));
        !           433:                                rootEntry = menu_get_parent_menu(menu);
        !           434:                                conf(rootEntry);
        !           435:                        }
        !           436:                }
        !           437:        }
        !           438: 
        !           439:        for (child = menu->list; child; child = child->next)
        !           440:                check_conf(child);
        !           441: }
        !           442: 
        !           443: static struct option long_opts[] = {
        !           444:        {"oldaskconfig",    no_argument,       NULL, oldaskconfig},
        !           445:        {"oldconfig",       no_argument,       NULL, oldconfig},
        !           446:        {"silentoldconfig", no_argument,       NULL, silentoldconfig},
        !           447:        {"defconfig",       optional_argument, NULL, defconfig},
        !           448:        {"savedefconfig",   required_argument, NULL, savedefconfig},
        !           449:        {"allnoconfig",     no_argument,       NULL, allnoconfig},
        !           450:        {"allyesconfig",    no_argument,       NULL, allyesconfig},
        !           451:        {"allmodconfig",    no_argument,       NULL, allmodconfig},
        !           452:        {"alldefconfig",    no_argument,       NULL, alldefconfig},
        !           453:        {"randconfig",      no_argument,       NULL, randconfig},
        !           454:        {"listnewconfig",   no_argument,       NULL, listnewconfig},
        !           455:        {"oldnoconfig",     no_argument,       NULL, oldnoconfig},
        !           456:        {NULL, 0, NULL, 0}
        !           457: };
        !           458: 
        !           459: int main(int ac, char **av)
        !           460: {
        !           461:        int opt;
        !           462:        const char *name;
        !           463:        struct stat tmpstat;
        !           464: 
        !           465:        setlocale(LC_ALL, "");
        !           466:        bindtextdomain(PACKAGE, LOCALEDIR);
        !           467:        textdomain(PACKAGE);
        !           468: 
        !           469:        while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
        !           470:                input_mode = (enum input_mode)opt;
        !           471:                switch (opt) {
        !           472:                case silentoldconfig:
        !           473:                        sync_kconfig = 1;
        !           474:                        break;
        !           475:                case defconfig:
        !           476:                case savedefconfig:
        !           477:                        defconfig_file = optarg;
        !           478:                        break;
        !           479:                case randconfig:
        !           480:                {
        !           481:                        struct timeval now;
        !           482:                        unsigned int seed;
        !           483: 
        !           484:                        /*
        !           485:                         * Use microseconds derived seed,
        !           486:                         * compensate for systems where it may be zero
        !           487:                         */
        !           488:                        gettimeofday(&now, NULL);
        !           489: 
        !           490:                        seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
        !           491:                        srand(seed);
        !           492:                        break;
        !           493:                }
        !           494:                case '?':
        !           495:                        fprintf(stderr, _("See README for usage info\n"));
        !           496:                        exit(1);
        !           497:                        break;
        !           498:                }
        !           499:        }
        !           500:        if (ac == optind) {
        !           501:                printf(_("%s: Kconfig file missing\n"), av[0]);
        !           502:                exit(1);
        !           503:        }
        !           504:        name = av[optind];
        !           505:        conf_parse(name);
        !           506:        //zconfdump(stdout);
        !           507:        if (sync_kconfig) {
        !           508:                name = conf_get_configname();
        !           509:                if (stat(name, &tmpstat)) {
        !           510:                        fprintf(stderr, _("***\n"
        !           511:                                "*** Configuration file \"%s\" not found!\n"
        !           512:                                "***\n"
        !           513:                                "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
        !           514:                                "*** \"make menuconfig\" or \"make xconfig\").\n"
        !           515:                                "***\n"), name);
        !           516:                        exit(1);
        !           517:                }
        !           518:        }
        !           519: 
        !           520:        switch (input_mode) {
        !           521:        case defconfig:
        !           522:                if (!defconfig_file)
        !           523:                        defconfig_file = conf_get_default_confname();
        !           524:                if (conf_read(defconfig_file)) {
        !           525:                        printf(_("***\n"
        !           526:                                "*** Can't find default configuration \"%s\"!\n"
        !           527:                                "***\n"), defconfig_file);
        !           528:                        exit(1);
        !           529:                }
        !           530:                break;
        !           531:        case savedefconfig:
        !           532:        case silentoldconfig:
        !           533:        case oldaskconfig:
        !           534:        case oldconfig:
        !           535:        case listnewconfig:
        !           536:        case oldnoconfig:
        !           537:                conf_read(NULL);
        !           538:                break;
        !           539:        case allnoconfig:
        !           540:        case allyesconfig:
        !           541:        case allmodconfig:
        !           542:        case alldefconfig:
        !           543:        case randconfig:
        !           544:                name = getenv("KCONFIG_ALLCONFIG");
        !           545:                if (name && !stat(name, &tmpstat)) {
        !           546:                        conf_read_simple(name, S_DEF_USER);
        !           547:                        break;
        !           548:                }
        !           549:                switch (input_mode) {
        !           550:                case allnoconfig:       name = "allno.config"; break;
        !           551:                case allyesconfig:      name = "allyes.config"; break;
        !           552:                case allmodconfig:      name = "allmod.config"; break;
        !           553:                case alldefconfig:      name = "alldef.config"; break;
        !           554:                case randconfig:        name = "allrandom.config"; break;
        !           555:                default: break;
        !           556:                }
        !           557:                if (!stat(name, &tmpstat))
        !           558:                        conf_read_simple(name, S_DEF_USER);
        !           559:                else if (!stat("all.config", &tmpstat))
        !           560:                        conf_read_simple("all.config", S_DEF_USER);
        !           561:                break;
        !           562:        default:
        !           563:                break;
        !           564:        }
        !           565: 
        !           566:        if (sync_kconfig) {
        !           567:                if (conf_get_changed()) {
        !           568:                        name = getenv("KCONFIG_NOSILENTUPDATE");
        !           569:                        if (name && *name) {
        !           570:                                fprintf(stderr,
        !           571:                                        _("\n*** The configuration requires explicit update.\n\n"));
        !           572:                                return 1;
        !           573:                        }
        !           574:                }
        !           575:                valid_stdin = isatty(0) && isatty(1) && isatty(2);
        !           576:        }
        !           577: 
        !           578:        switch (input_mode) {
        !           579:        case allnoconfig:
        !           580:                conf_set_all_new_symbols(def_no);
        !           581:                break;
        !           582:        case allyesconfig:
        !           583:                conf_set_all_new_symbols(def_yes);
        !           584:                break;
        !           585:        case allmodconfig:
        !           586:                conf_set_all_new_symbols(def_mod);
        !           587:                break;
        !           588:        case alldefconfig:
        !           589:                conf_set_all_new_symbols(def_default);
        !           590:                break;
        !           591:        case randconfig:
        !           592:                conf_set_all_new_symbols(def_random);
        !           593:                break;
        !           594:        case defconfig:
        !           595:                conf_set_all_new_symbols(def_default);
        !           596:                break;
        !           597:        case savedefconfig:
        !           598:                break;
        !           599:        case oldaskconfig:
        !           600:                rootEntry = &rootmenu;
        !           601:                conf(&rootmenu);
        !           602:                input_mode = silentoldconfig;
        !           603:                /* fall through */
        !           604:        case oldconfig:
        !           605:        case listnewconfig:
        !           606:        case oldnoconfig:
        !           607:        case silentoldconfig:
        !           608:                /* Update until a loop caused no more changes */
        !           609:                do {
        !           610:                        conf_cnt = 0;
        !           611:                        check_conf(&rootmenu);
        !           612:                } while (conf_cnt &&
        !           613:                         (input_mode != listnewconfig &&
        !           614:                          input_mode != oldnoconfig));
        !           615:                break;
        !           616:        }
        !           617: 
        !           618:        if (sync_kconfig) {
        !           619:                /* silentoldconfig is used during the build so we shall update autoconf.
        !           620:                 * All other commands are only used to generate a config.
        !           621:                 */
        !           622:                if (conf_get_changed() && conf_write(NULL)) {
        !           623:                        fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
        !           624:                        exit(1);
        !           625:                }
        !           626:                if (conf_write_autoconf()) {
        !           627:                        fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
        !           628:                        return 1;
        !           629:                }
        !           630:        } else if (input_mode == savedefconfig) {
        !           631:                if (conf_write_defconfig(defconfig_file)) {
        !           632:                        fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
        !           633:                                defconfig_file);
        !           634:                        return 1;
        !           635:                }
        !           636:        } else if (input_mode != listnewconfig) {
        !           637:                if (conf_write(NULL)) {
        !           638:                        fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
        !           639:                        exit(1);
        !           640:                }
        !           641:        }
        !           642:        return 0;
        !           643: }
        !           644: /*
        !           645:  * Helper function to facilitate fgets() by Jean Sacren.
        !           646:  */
        !           647: void xfgets(str, size, in)
        !           648:        char *str;
        !           649:        int size;
        !           650:        FILE *in;
        !           651: {
        !           652:        if (fgets(str, size, in) == NULL)
        !           653:                fprintf(stderr, "\nError in reading or end of file.\n");
        !           654: }

unix.superglobalmegacorp.com

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