[BACK]Return to util.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / distrib / utils / sysinst

Annotation of src/distrib/utils/sysinst/util.c, Revision 1.67.2.8

1.67.2.8! jmc         1: /*     $NetBSD$        */
1.1       phil        2:
                      3: /*
                      4:  * Copyright 1997 Piermont Information Systems Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Philip A. Nelson for Piermont Information Systems Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
1.42      cgd        19:  *      This product includes software developed for the NetBSD Project by
1.1       phil       20:  *      Piermont Information Systems Inc.
                     21:  * 4. The name of Piermont Information Systems Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
                     26:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
                     29:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     35:  * THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39: /* util.c -- routines that don't really fit anywhere else... */
                     40:
                     41: #include <stdio.h>
1.10      jonathan   42: #include <stdarg.h>
1.1       phil       43: #include <unistd.h>
1.5       phil       44: #include <sys/types.h>
1.4       phil       45: #include <sys/param.h>
                     46: #include <sys/sysctl.h>
1.5       phil       47: #include <sys/stat.h>
1.2       phil       48: #include <curses.h>
1.37      bouyer     49: #include <errno.h>
1.52      hubertf    50: #include <fts.h>
1.64      mrg        51: #include <util.h>
1.1       phil       52: #include "defs.h"
1.5       phil       53: #include "md.h"
1.1       phil       54: #include "msg_defs.h"
                     55: #include "menu_defs.h"
1.4       phil       56:
1.14      jonathan   57: /*
                     58:  * local prototypes
                     59:  */
1.29      mrg        60: struct  tarstats {
1.22      jonathan   61:        int nselected;
                     62:        int nfound;
                     63:        int nnotfound;
                     64:        int nerror;
                     65:        int nsuccess;
1.44      cgd        66:        int nskipped;
1.22      jonathan   67: } tarstats;
                     68:
1.61      mrg        69: int    extract_file (char *path);
                     70: int    extract_dist (void);
                     71: int    cleanup_dist (const char *path);
                     72: int    distribution_sets_exist_p (const char *path);
                     73: static int check_for (unsigned int mode, const char *pathname);
1.4       phil       74:
1.29      mrg        75: int
                     76: dir_exists_p(path)
                     77:        const char *path;
1.22      jonathan   78: {
1.54      fvdl       79:        return file_mode_match(path, S_IFDIR);
                     80: }
1.29      mrg        81:
1.54      fvdl       82: int
                     83: file_exists_p(path)
                     84:        const char *path;
                     85: {
                     86:        return file_mode_match(path, S_IFREG);
1.22      jonathan   87: }
                     88:
1.29      mrg        89: int
1.54      fvdl       90: file_mode_match(path, mode)
1.29      mrg        91:        const char *path;
1.54      fvdl       92:        unsigned int mode;
1.22      jonathan   93: {
1.54      fvdl       94:        struct stat st;
1.29      mrg        95:
1.54      fvdl       96:        return (stat(path, &st) == 0 && (st.st_mode & mode) != 0);
1.22      jonathan   97: }
                     98:
1.29      mrg        99: int
                    100: distribution_sets_exist_p(path)
                    101:        const char *path;
1.22      jonathan  102: {
                    103:        char buf[STRSIZE];
                    104:        int result;
                    105:
                    106:        result = 1;
                    107:        snprintf(buf, STRSIZE, "%s/%s", path, "etc.tgz");
1.59      hubertf   108:        result = result && file_exists_p(buf);
                    109:
1.62      jdc       110:        snprintf(buf, STRSIZE, "%s/%s", path, "base.tgz");
                    111:        result = result && file_exists_p(buf);
                    112:
1.22      jonathan  113:        return(result);
                    114: }
                    115:
                    116:
1.29      mrg       117: void
                    118: get_ramsize()
1.4       phil      119: {
1.29      mrg       120:        long len = sizeof(long);
1.4       phil      121:        int mib[2] = {CTL_HW, HW_PHYSMEM};
                    122:
                    123:        sysctl(mib, 2, (void *)&ramsize, (size_t *)&len, NULL, 0);
                    124:
                    125:        /* Find out how many Megs ... round up. */
                    126:        rammb = (ramsize + MEG - 1) / MEG;
                    127: }
                    128:
1.1       phil      129: static int asked = 0;
                    130:
1.29      mrg       131: void
1.50      fvdl      132: ask_sizemult(cylsize)
                    133:        int cylsize;
1.1       phil      134: {
1.50      fvdl      135:        current_cylsize = cylsize;      /* XXX */
1.29      mrg       136:
1.1       phil      137:        if (!asked) {
1.50      fvdl      138:                msg_display(MSG_sizechoice);
1.29      mrg       139:                process_menu(MENU_sizechoice);
1.1       phil      140:        }
                    141:        asked = 1;
1.9       phil      142: }
                    143:
1.29      mrg       144: void
1.50      fvdl      145: reask_sizemult(cylsize)
                    146:        int cylsize;
1.9       phil      147: {
1.29      mrg       148:
1.9       phil      149:        asked = 0;
1.50      fvdl      150:        ask_sizemult(cylsize);
1.1       phil      151: }
                    152:
1.29      mrg       153: void
                    154: run_makedev()
1.3       phil      155: {
1.22      jonathan  156:        char *owd;
                    157:
1.39      bouyer    158:        wclear(stdscr);
                    159:        wrefresh(stdscr);
1.29      mrg       160:        msg_display(MSG_makedev);
1.5       phil      161:        sleep (1);
1.14      jonathan  162:
1.29      mrg       163:        owd = getcwd(NULL,0);
1.22      jonathan  164:
1.14      jonathan  165:        /* make /dev, in case the user  didn't extract it. */
                    166:        make_target_dir("/dev");
1.10      jonathan  167:        target_chdir_or_die("/dev");
1.56      fvdl      168:        run_prog(0, NULL, "/bin/sh MAKEDEV all");
1.22      jonathan  169:
                    170:        chdir(owd);
                    171:        free(owd);
1.5       phil      172: }
                    173:
                    174:
1.29      mrg       175: /*
                    176:  * Load files from floppy.  Requires a /mnt2 directory for mounting them.
                    177:  */
                    178: int
                    179: get_via_floppy()
1.5       phil      180: {
                    181:        char distname[STRSIZE];
                    182:        char fddev[STRSIZE] = "/dev/fd0a";
                    183:        char fname[STRSIZE];
                    184:        char fullname[STRSIZE];
1.34      garbled   185:        char catcmd[STRSIZE];
1.7       phil      186:        distinfo *list;
1.5       phil      187:        char post[4];
                    188:        int  mounted = 0;
1.8       phil      189:        int  first;
1.5       phil      190:        struct stat sb;
                    191:
1.29      mrg       192:        cd_dist_dir("unloading from floppy");
1.7       phil      193:
1.29      mrg       194:        msg_prompt_add(MSG_fddev, fddev, fddev, STRSIZE);
1.5       phil      195:
                    196:        list = dist_list;
1.7       phil      197:        while (list->name) {
1.29      mrg       198:                strcpy(post, ".aa");
                    199:                snprintf(distname, STRSIZE, "%s%s", list->name, dist_postfix);
1.8       phil      200:                while (list->getit && strcmp(&post[1],list->fdlast) <= 0) {
1.29      mrg       201:                        snprintf(fname, STRSIZE, "%s%s", list->name, post);
                    202:                        snprintf(fullname, STRSIZE, "/mnt2/%s", fname);
1.8       phil      203:                        first = 1;
1.5       phil      204:                        while (!mounted || stat(fullname, &sb)) {
1.8       phil      205:                                if (mounted)
1.56      fvdl      206:                                  run_prog(0, NULL, "/sbin/umount /mnt2");
1.8       phil      207:                                if (first)
1.29      mrg       208:                                        msg_display(MSG_fdmount, fname);
1.8       phil      209:                                else
1.29      mrg       210:                                        msg_display(MSG_fdnotfound, fname);
                    211:                                process_menu(MENU_fdok);
1.8       phil      212:                                if (!yesno)
                    213:                                        return 0;
1.56      fvdl      214:                                while (run_prog(0, NULL,
1.35      bouyer    215:                                    "/sbin/mount -r -t %s %s /mnt2",
1.29      mrg       216:                                    fdtype, fddev)) {
                    217:                                        msg_display(MSG_fdremount, fname);
                    218:                                        process_menu(MENU_fdremount);
1.5       phil      219:                                        if (!yesno)
                    220:                                                return 0;
                    221:                                }
                    222:                                mounted = 1;
1.8       phil      223:                                first = 0;
1.5       phil      224:                        }
1.34      garbled   225:                        sprintf(catcmd, "/bin/cat %s >> %s",
                    226:                                fullname, distname);
                    227:                        if (logging)
                    228:                                (void)fprintf(log, "%s\n", catcmd);
                    229:                        if (scripting)
                    230:                                (void)fprintf(script, "%s\n", catcmd);
                    231:                        do_system(catcmd);
1.8       phil      232:                        if (post[2] < 'z')
                    233:                                post[2]++;
1.5       phil      234:                        else
1.29      mrg       235:                                post[2] = 'a', post[1]++;
1.5       phil      236:                }
1.56      fvdl      237:                run_prog(0, NULL, "/sbin/umount /mnt2");
1.5       phil      238:                mounted = 0;
                    239:                list++;
                    240:        }
                    241: #ifndef DEBUG
1.10      jonathan  242:        chdir("/");     /* back to current real root */
1.5       phil      243: #endif
1.6       phil      244:        return 1;
                    245: }
                    246:
1.29      mrg       247: /*
                    248:  * Get from a CDROM distribution.
                    249:  */
1.6       phil      250: int
1.29      mrg       251: get_via_cdrom()
1.6       phil      252: {
1.22      jonathan  253:        char tmpdir[STRSIZE];
1.28      fvdl      254:
                    255:        /* Get CD-rom device name and path within CD-rom */
1.29      mrg       256:        process_menu(MENU_cdromsource);
1.6       phil      257:
1.22      jonathan  258: again:
1.56      fvdl      259:        run_prog(0, NULL, "/sbin/umount /mnt2");
1.22      jonathan  260:
1.6       phil      261:        /* Mount it */
1.56      fvdl      262:        if (run_prog(0, NULL,
1.35      bouyer    263:            "/sbin/mount -rt cd9660 /dev/%sa /mnt2", cdrom_dev)) {
1.22      jonathan  264:                msg_display(MSG_badsetdir, cdrom_dev);
1.29      mrg       265:                process_menu(MENU_cdrombadmount);
1.6       phil      266:                if (!yesno)
                    267:                        return 0;
1.22      jonathan  268:                if (!ignorerror)
                    269:                        goto again;
                    270:        }
                    271:
                    272:        snprintf(tmpdir, STRSIZE, "%s/%s", "/mnt2", cdrom_dir);
                    273:
                    274:        /* Verify distribution files exist.  */
                    275:        if (distribution_sets_exist_p(tmpdir) == 0) {
                    276:                msg_display(MSG_badsetdir, tmpdir);
1.29      mrg       277:                process_menu(MENU_cdrombadmount);
1.22      jonathan  278:                if (!yesno)
                    279:                        return (0);
                    280:                if (!ignorerror)
                    281:                        goto again;
1.6       phil      282:        }
                    283:
                    284:        /* return location, don't clean... */
1.22      jonathan  285:        strncpy(ext_dir, tmpdir, STRSIZE);
1.6       phil      286:        clean_dist_dir = 0;
                    287:        mnt2_mounted = 1;
1.5       phil      288:        return 1;
1.7       phil      289: }
                    290:
1.22      jonathan  291:
                    292: /*
                    293:  * Get from a pathname inside an unmounted local filesystem
                    294:  * (e.g., where sets were preloaded onto a local DOS partition)
                    295:  */
1.29      mrg       296: int
                    297: get_via_localfs()
1.16      mhitch    298: {
1.22      jonathan  299:        char tmpdir[STRSIZE];
                    300:
1.16      mhitch    301:        /* Get device, filesystem, and filepath */
                    302:        process_menu (MENU_localfssource);
                    303:
1.22      jonathan  304: again:
1.56      fvdl      305:        run_prog(0, NULL, "/sbin/umount /mnt2");
1.22      jonathan  306:
1.16      mhitch    307:        /* Mount it */
1.56      fvdl      308:        if (run_prog(0, NULL, "/sbin/mount -rt %s /dev/%s /mnt2",
1.35      bouyer    309:            localfs_fs, localfs_dev)) {
1.22      jonathan  310:
1.29      mrg       311:                msg_display(MSG_localfsbadmount, localfs_dir, localfs_dev);
                    312:                process_menu(MENU_localfsbadmount);
1.16      mhitch    313:                if (!yesno)
                    314:                        return 0;
1.22      jonathan  315:                if (!ignorerror)
1.29      mrg       316:                        goto again;
1.22      jonathan  317:        }
                    318:
                    319:        snprintf(tmpdir, STRSIZE, "%s/%s", "/mnt2", localfs_dir);
                    320:
                    321:        /* Verify distribution files exist.  */
                    322:        if (distribution_sets_exist_p(tmpdir) == 0) {
                    323:                msg_display(MSG_badsetdir, tmpdir);
1.29      mrg       324:                process_menu(MENU_localfsbadmount);
1.22      jonathan  325:                if (!yesno)
                    326:                        return 0;
                    327:                if (!ignorerror)
                    328:                        goto again;
1.16      mhitch    329:        }
                    330:
                    331:        /* return location, don't clean... */
1.22      jonathan  332:        strncpy(ext_dir, tmpdir, STRSIZE);
1.16      mhitch    333:        clean_dist_dir = 0;
                    334:        mnt2_mounted = 1;
                    335:        return 1;
                    336: }
1.7       phil      337:
1.29      mrg       338: /*
                    339:  * Get from an already-mounted pathname.
                    340:  */
1.22      jonathan  341:
                    342: int get_via_localdir(void)
                    343: {
                    344:
                    345:        /* Get device, filesystem, and filepath */
1.29      mrg       346:        process_menu(MENU_localdirsource);
1.22      jonathan  347:
                    348: again:
                    349:        /* Complain if not a directory */
                    350:        if (dir_exists_p(localfs_dir) == 0) {
                    351:
1.29      mrg       352:                msg_display(MSG_badlocalsetdir, localfs_dir);
                    353:                process_menu(MENU_localdirbad);
1.22      jonathan  354:                if (!yesno)
                    355:                        return (0);
                    356:                if (!ignorerror)
                    357:                        goto again;
                    358:        }
                    359:
                    360:        /* Verify distribution files exist.  */
                    361:        if (distribution_sets_exist_p(localfs_dir) == 0) {
                    362:                msg_display(MSG_badsetdir, localfs_dir);
1.29      mrg       363:                process_menu(MENU_localdirbad);
1.22      jonathan  364:                if (!yesno)
                    365:                        return (0);
                    366:                if (!ignorerror)
                    367:                        goto again;
                    368:        }
                    369:
                    370:        /* return location, don't clean... */
1.29      mrg       371:        strncpy(ext_dir, localfs_dir, STRSIZE);
1.22      jonathan  372:        clean_dist_dir = 0;
                    373:        mnt2_mounted = 0;
                    374:        return 1;
                    375: }
                    376:
                    377:
1.29      mrg       378: void
                    379: cd_dist_dir(forwhat)
                    380:        char *forwhat;
1.7       phil      381: {
1.19      phil      382:        char *cwd;
                    383:
1.10      jonathan  384:        /* ask user for the mountpoint. */
1.29      mrg       385:        msg_prompt(MSG_distdir, dist_dir, dist_dir, STRSIZE, forwhat);
1.10      jonathan  386:
                    387:        /* make sure the directory exists. */
                    388:        make_target_dir(dist_dir);
1.7       phil      389:
                    390:        clean_dist_dir = 1;
1.10      jonathan  391:        target_chdir_or_die(dist_dir);
1.19      phil      392:
                    393:        /* Set ext_dir for absolute path. */
1.29      mrg       394:        cwd = getcwd(NULL,0);
                    395:        strncpy(ext_dir, cwd, STRSIZE);
1.19      phil      396:        free (cwd);
1.7       phil      397: }
                    398:
1.10      jonathan  399:
1.29      mrg       400: /*
                    401:  * Support for custom distribution fetches / unpacks.
                    402:  */
                    403: void
                    404: toggle_getit(num)
                    405:        int num;
                    406: {
1.7       phil      407:
                    408:        dist_list[num].getit ^= 1;
                    409: }
                    410:
1.29      mrg       411: void
                    412: show_cur_distsets()
1.7       phil      413: {
                    414:        distinfo *list;
                    415:
1.29      mrg       416:        msg_display(MSG_cur_distsets);
1.48      cgd       417:        msg_table_add(MSG_cur_distsets_header);
1.7       phil      418:        list = dist_list;
                    419:        while (list->name) {
1.48      cgd       420:                msg_table_add(MSG_cur_distsets_row, list->desc,
1.29      mrg       421:                    list->getit ? msg_string(MSG_yes) : msg_string(MSG_no));
1.7       phil      422:                list++;
                    423:        }
1.1       phil      424: }
1.10      jonathan  425:
1.12      phil      426: /* Do we want a verbose extract? */
                    427: static int verbose = -1;
                    428:
                    429: void
1.29      mrg       430: ask_verbose_dist()
1.12      phil      431: {
1.29      mrg       432:
1.12      phil      433:        if (verbose < 0) {
1.29      mrg       434:                msg_display(MSG_verboseextract);
                    435:                process_menu(MENU_noyes);
1.12      phil      436:                verbose = yesno;
1.36      bouyer    437:                wclear(stdscr);
                    438:                wrefresh(stdscr);
1.12      phil      439:        }
                    440: }
                    441:
1.44      cgd       442: int
1.29      mrg       443: extract_file(path)
                    444:        char *path;
1.12      phil      445: {
                    446:        char *owd;
1.44      cgd       447:        int   tarexit, rv;
1.12      phil      448:
                    449:        owd = getcwd (NULL,0);
                    450:
1.22      jonathan  451:        /* check tarfile exists */
                    452:        if (!file_exists_p(path)) {
                    453:                tarstats.nnotfound++;
1.44      cgd       454:
                    455:                msg_display(MSG_notarfile, path);
                    456:                process_menu(MENU_noyes);
                    457:                return (yesno == 0);
1.22      jonathan  458:        }
                    459:
                    460:        tarstats.nfound++;
1.14      jonathan  461:        /* cd to the target root. */
1.12      phil      462:        target_chdir_or_die("/");
                    463:
1.14      jonathan  464:        /* now extract set files files into "./". */
1.56      fvdl      465:        tarexit = run_prog(RUN_DISPLAY, NULL,
1.67.2.8! jmc       466:            "pax -zr%spe -O -f %s", verbose ? "v" : "", path);
1.22      jonathan  467:
1.17      phil      468:        /* Check tarexit for errors and give warning. */
1.22      jonathan  469:        if (tarexit) {
                    470:                tarstats.nerror++;
1.44      cgd       471:
                    472:                msg_display(MSG_tarerror, path);
                    473:                process_menu(MENU_noyes);
                    474:                rv = (yesno == 0);
1.22      jonathan  475:        } else {
                    476:                tarstats.nsuccess++;
1.44      cgd       477:                rv = 0;
1.22      jonathan  478:        }
                    479:
1.29      mrg       480:        chdir(owd);
                    481:        free(owd);
1.44      cgd       482:
                    483:        return (rv);
1.12      phil      484: }
                    485:
1.19      phil      486:
1.29      mrg       487: /*
1.37      bouyer    488:  * Extract_dist **REQUIRES** an absolute path in ext_dir.  Any code
1.19      phil      489:  * that sets up dist_dir for use by extract_dist needs to put in the
                    490:  * full path name to the directory.
                    491:  */
                    492:
1.22      jonathan  493: int
1.29      mrg       494: extract_dist()
1.12      phil      495: {
                    496:        char distname[STRSIZE];
                    497:        char fname[STRSIZE];
                    498:        distinfo *list;
1.44      cgd       499:        int punt;
1.12      phil      500:
1.22      jonathan  501:        /* reset failure/success counters */
1.31      perry     502:        memset(&tarstats, 0, sizeof(tarstats));
1.22      jonathan  503:
1.32      garbled   504:        /*endwin();*/
1.44      cgd       505:        for (punt = 0, list = dist_list; list->name != NULL; list++) {
1.15      phil      506:                if (list->getit) {
1.22      jonathan  507:                        tarstats.nselected++;
1.44      cgd       508:                        if (punt) {
                    509:                                tarstats.nskipped++;
                    510:                                continue;
                    511:                        }
1.37      bouyer    512:                        if (cleanup_dist(list->name) == 0) {
                    513:                                msg_display(MSG_cleanup_warn);
                    514:                                process_menu(MENU_ok);
                    515:                        }
1.29      mrg       516:                        (void)snprintf(distname, STRSIZE, "%s%s", list->name,
                    517:                            dist_postfix);
                    518:                        (void)snprintf(fname, STRSIZE, "%s/%s", ext_dir,
                    519:                            distname);
1.44      cgd       520:
                    521:                        /* if extraction failed and user aborted, punt. */
                    522:                        punt = extract_file(fname);
1.15      phil      523:                }
1.12      phil      524:        }
1.22      jonathan  525:
1.63      jdc       526:        wrefresh(curscr);
1.60      jdc       527:        wmove(stdscr, 0, 0);
1.43      cgd       528:        wclear(stdscr);
1.17      phil      529:        wrefresh(stdscr);
1.22      jonathan  530:
                    531:        if (tarstats.nerror == 0 && tarstats.nsuccess == tarstats.nselected) {
1.29      mrg       532:                msg_display(MSG_endtarok);
                    533:                process_menu(MENU_ok);
1.22      jonathan  534:                return 0;
                    535:        } else {
                    536:                /* We encountered  errors. Let the user know. */
                    537:                msg_display(MSG_endtar,
1.44      cgd       538:                    tarstats.nselected, tarstats.nnotfound, tarstats.nskipped,
1.22      jonathan  539:                    tarstats.nfound, tarstats.nsuccess, tarstats.nerror);
1.29      mrg       540:                process_menu(MENU_ok);
1.22      jonathan  541:                return 1;
                    542:        }
1.12      phil      543: }
                    544:
1.11      jonathan  545: /*
1.37      bouyer    546:  * Do pre-extract cleanup for set 'name':
                    547:  * open a file named '/dist/<name>_obsolete file', which contain a list of
                    548:  * files to kill from the target. For each file, test if it is present on
                    549:  * the target. Then display the list of files which will be removed,
                    550:  * ask user for confirmation, and process.
1.62      jdc       551:  * Non-empty directories will be renamed to <directory.old>.
1.37      bouyer    552:  */
                    553:
                    554: /* definition for a list of files. */
                    555: struct filelist {
                    556:        struct filelist *next;
                    557:        char name[MAXPATHLEN];
                    558:        mode_t type;
                    559: };
                    560:
                    561: int
                    562: cleanup_dist(name)
                    563:        const char *name;
                    564: {
                    565:        char file_path[MAXPATHLEN];
                    566:        char file_name[MAXPATHLEN];
                    567:        FILE *list_file;
                    568:        struct filelist *head = NULL;
                    569:        struct filelist *current;
                    570:        int saved_errno;
                    571:        struct stat st;
                    572:        int retval = 1;
                    573:        int needok = 0;
                    574:
                    575:        snprintf(file_path, MAXPATHLEN, "/dist/%s_obsolete", name);
                    576:        list_file = fopen(file_path, "r");
                    577:        if (list_file == NULL) {
                    578:                saved_errno = errno;
                    579:                if (logging)
                    580:                        fprintf(log, "Open of %s failed: %s\n", file_path,
                    581:                            strerror(saved_errno));
                    582:                if (saved_errno == ENOENT)
                    583:                        return 1;
                    584:                msg_display_add(MSG_openfail, name, strerror(saved_errno));
                    585:                process_menu(MENU_ok);
                    586:                return 0;
                    587:        }
                    588:        while (fgets(file_name, MAXPATHLEN, list_file)) {
                    589:                /* ignore lines that don't begin with '/' */
                    590:                if (file_name[0] != '/')
                    591:                        continue;
                    592:                /* Remove trailing \n if any */
                    593:                if (file_name[strlen(file_name)-1] == '\n')
                    594:                        file_name[strlen(file_name)-1] = '\0';
                    595:                snprintf(file_path, MAXPATHLEN, "%s%s", target_prefix(),
                    596:                    file_name);
                    597:                if (lstat(file_path, &st) != 0) {
                    598:                        saved_errno = errno;
                    599:                        if (logging)
                    600:                                fprintf(log, "stat() of %s failed: %s\n",
                    601:                                    file_path, strerror(saved_errno));
                    602:                        if (saved_errno == ENOENT)
                    603:                                continue;
                    604:                        msg_display_add(MSG_statfail, file_path,
                    605:                            strerror(saved_errno));
                    606:                        process_menu(MENU_ok);
                    607:                        return 0;
                    608:                }
                    609:                if (head == NULL) {
                    610:                        head = current = malloc(sizeof(struct filelist));
                    611:                        if (head == NULL) {
                    612:                                fprintf(stderr, "out of memory\n");
                    613:                                exit(1);
                    614:                        }
                    615:                } else {
                    616:                        current->next = malloc(sizeof(struct filelist));
1.67.2.3  lukem     617:                        if (current->next == NULL) {
1.37      bouyer    618:                                fprintf(stderr, "out of memory\n");
                    619:                                exit(1);
                    620:                        }
                    621:                        current = current->next;
                    622:                }
                    623:                current->next = NULL;
                    624:                snprintf(current->name, MAXPATHLEN, "%s", file_path);
                    625:                current->type = st.st_mode & S_IFMT;
                    626:                if (logging)
                    627:                        fprintf(log, "Adding file %s, type %d to list of "
                    628:                            "obsolete file\n", current->name, current->type);
                    629:        }
1.62      jdc       630:        fclose(list_file);
1.37      bouyer    631:        if (head == NULL)
1.38      bouyer    632:                return 1;
1.37      bouyer    633: #if 0
                    634:        /* XXX doesn't work, too many files printed ! */
                    635:        msg_display(MSG_deleting_files);
                    636:        for (current = head; current != NULL; current = current->next) {
1.49      cgd       637:                if (current->type != S_IFDIR) {
                    638:                        /* XXX msg_printf_add going/gone away */
1.37      bouyer    639:                        msg_printf_add("%s ", current->name);
1.49      cgd       640:                }
1.37      bouyer    641:        }
                    642:        msg_display_add(MSG_deleting_dirs);
                    643:        for (current = head; current != NULL; current = current->next) {
1.49      cgd       644:                if (current->type == S_IFDIR) {
                    645:                        /* XXX msg_printf_add going/gone away */
1.37      bouyer    646:                        msg_printf_add("%s ", current->name);
1.49      cgd       647:                }
1.37      bouyer    648:        }
                    649:        process_menu(MENU_ok);
                    650: #endif
                    651:        /* first remove files */
                    652:        for (current = head; current != NULL; current = current->next) {
                    653:                if (current->type == S_IFDIR)
                    654:                        continue;
                    655:                if (scripting)
                    656:                        (void)fprintf(script, "rm %s\n", current->name);
                    657:                if (unlink(current->name) != 0) {
                    658:                        saved_errno = errno;
1.51      hubertf   659:                        if (saved_errno == ENOENT)
                    660:                                continue;       /* don't worry about
                    661:                                                   non-existing files */
1.37      bouyer    662:                        if (logging)
                    663:                                fprintf(log, "rm %s failed: %s\n",
                    664:                                    current->name, strerror(saved_errno));
                    665:                        msg_display_add(MSG_unlink_fail, current->name,
                    666:                            strerror(saved_errno));
                    667:                        retval = 0;
                    668:                        needok = 1;
                    669:                }
                    670:
                    671:        }
                    672:        /* now dirs */
                    673:        for (current = head; current != NULL; current = current->next) {
                    674:                if (current->type != S_IFDIR)
                    675:                        continue;
                    676:                if (rmdir(current->name) == 0) {
                    677:                        if (scripting)
                    678:                                (void)fprintf(script, "rmdir %s\n",
                    679:                                    current->name);
                    680:                        continue;
                    681:                }
                    682:                saved_errno = errno;
                    683:                if (saved_errno == ENOTEMPTY) {
                    684:                        if (logging)
                    685:                                fprintf(log, "dir %s not empty, "
                    686:                                    "trying to rename to %s.old\n",
                    687:                                    current->name, current->name);
                    688:                        snprintf(file_path, MAXPATHLEN,
                    689:                            "%s.old", current->name);
                    690:                        if (scripting)
                    691:                                (void)fprintf(script, "mv %s %s\n",
                    692:                                    current->name, file_path);
                    693:                        needok = 1;
                    694:                        if (rename(current->name, file_path) != 0) {
                    695:                                saved_errno = errno;
                    696:                                if (logging)
                    697:                                        fprintf(log, "mv %s %s failed: %s\n",
                    698:                                            current->name, file_path,
                    699:                                            strerror(saved_errno));
                    700:                                msg_display_add(MSG_rename_fail, current->name,
                    701:                                    file_path, strerror(errno));
                    702:                                 retval = 0;
                    703:                        }
                    704:                        msg_display_add(MSG_renamed_dir, current->name,
                    705:                            file_path);
                    706:                } else { /* rmdir error */
1.55      fvdl      707:                        /*
                    708:                         * Don't worry about non-existing directories.
                    709:                         */
                    710:                        if (saved_errno == ENOENT)
                    711:                                continue;
1.37      bouyer    712:                        if (logging)
                    713:                                fprintf(log, "rm %s failed: %s\n",
                    714:                                    current->name, strerror(saved_errno));
                    715:                        msg_display_add(MSG_unlink_fail, current->name,
                    716:                            strerror(saved_errno));
                    717:                        retval = 0;
                    718:                        needok = 1;
                    719:                }
                    720:        }
                    721:        if (needok)
                    722:                process_menu(MENU_ok);
                    723:        return retval;
                    724: }
                    725:
                    726: /*
1.29      mrg       727:  * Get and unpack the distribution.
                    728:  * show success_msg if installation completes. Otherwise,,
                    729:  * show failure_msg and wait for the user to ack it before continuing.
1.11      jonathan  730:  * success_msg and failure_msg must both be 0-adic messages.
                    731:  */
1.45      cgd       732: int
1.29      mrg       733: get_and_unpack_sets(success_msg, failure_msg)
1.47      cgd       734:        msg success_msg;
                    735:        msg failure_msg;
1.11      jonathan  736: {
1.29      mrg       737:
1.20      jonathan  738:        /* Ensure mountpoint for distribution files exists in current root. */
1.32      garbled   739:        (void) mkdir("/mnt2", S_IRWXU| S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
                    740:        if (scripting)
                    741:                (void)fprintf(script, "mkdir /mnt2\nchmod 755 /mnt2\n");
1.20      jonathan  742:
1.26      phil      743:        /* Find out which files to "get" if we get files. */
1.37      bouyer    744:        wclear(stdscr);
                    745:        wrefresh(stdscr);
1.29      mrg       746:        process_menu(MENU_distset);
1.26      phil      747:
1.37      bouyer    748:        /* ask user whether to do normal or verbose extraction */
                    749:        ask_verbose_dist();
                    750:
1.11      jonathan  751:        /* Get the distribution files */
1.46      cgd       752:        do {
                    753:                got_dist = 0;
                    754:                process_menu(MENU_distmedium);
                    755:        } while (got_dist == -1);
1.26      phil      756:
1.11      jonathan  757:        if (nodist)
1.45      cgd       758:                return 1;
1.20      jonathan  759:
1.22      jonathan  760:        if (got_dist) {
1.11      jonathan  761:
1.22      jonathan  762:                /* Extract the distribution, abort on errors. */
1.45      cgd       763:                if (extract_dist())
                    764:                        return 1;
1.11      jonathan  765:
                    766:                /* Configure the system */
1.29      mrg       767:                run_makedev();
1.11      jonathan  768:
                    769:                /* Other configuration. */
                    770:                mnt_net_config();
                    771:
1.19      phil      772:                /* Clean up dist dir (use absolute path name) */
1.11      jonathan  773:                if (clean_dist_dir)
1.56      fvdl      774:                        run_prog(0, NULL, "/bin/rm -rf %s", ext_dir);
1.11      jonathan  775:
                    776:                /* Mounted dist dir? */
                    777:                if (mnt2_mounted)
1.56      fvdl      778:                        run_prog(0, NULL, "/sbin/umount /mnt2");
1.14      jonathan  779:
1.29      mrg       780:                /* Install/Upgrade complete ... reboot or exit to script */
                    781:                msg_display(success_msg);
                    782:                process_menu(MENU_ok);
1.45      cgd       783:                return 0;
1.22      jonathan  784:        }
                    785:
1.29      mrg       786:        msg_display(failure_msg);
                    787:        process_menu(MENU_ok);
1.45      cgd       788:        return 1;
1.14      jonathan  789: }
1.22      jonathan  790:
                    791:
1.14      jonathan  792:
                    793: /*
                    794:  * Do a quick sanity check that  the target can reboot.
                    795:  * return 1 if everything OK, 0 if there is a problem.
                    796:  * Uses a table of files we expect to find after a base install/upgrade.
                    797:  */
                    798:
                    799: /* test flag and pathname to check for after unpacking. */
1.54      fvdl      800: struct check_table { unsigned int mode; const char *path;} checks[] = {
                    801:   { S_IFREG, "/netbsd" },
                    802:   { S_IFDIR, "/etc" },
                    803:   { S_IFREG, "/etc/fstab" },
                    804:   { S_IFREG, "/sbin/init" },
                    805:   { S_IFREG, "/bin/sh" },
                    806:   { S_IFREG, "/etc/rc" },
                    807:   { S_IFREG, "/etc/rc.subr" },
                    808:   { S_IFREG, "/etc/rc.conf" },
                    809:   { S_IFDIR, "/dev" },
                    810:   { S_IFCHR, "/dev/console" },
1.14      jonathan  811: /* XXX check for rootdev in target /dev? */
1.54      fvdl      812:   { S_IFREG, "/etc/fstab" },
                    813:   { S_IFREG, "/sbin/fsck" },
                    814:   { S_IFREG, "/sbin/fsck_ffs" },
                    815:   { S_IFREG, "/sbin/mount" },
                    816:   { S_IFREG, "/sbin/mount_ffs" },
                    817:   { S_IFREG, "/sbin/mount_nfs" },
1.20      jonathan  818: #if defined(DEBUG) || defined(DEBUG_CHECK)
1.54      fvdl      819:   { S_IFREG, "/foo/bar" },             /* bad entry to exercise warning */
1.14      jonathan  820: #endif
                    821:   { 0, 0 }
                    822:
                    823: };
                    824:
                    825: /*
                    826:  * Check target for a single file.
                    827:  */
1.29      mrg       828: static int
1.54      fvdl      829: check_for(mode, pathname)
                    830:        unsigned int mode;
1.29      mrg       831:        const char *pathname;
1.14      jonathan  832: {
1.18      jonathan  833:        int found;
1.14      jonathan  834:
1.54      fvdl      835:        found = (target_test(mode, pathname) == 0);
1.18      jonathan  836:        if (found == 0)
1.14      jonathan  837:                msg_display(MSG_rootmissing, pathname);
1.18      jonathan  838:        return found;
1.14      jonathan  839: }
                    840:
1.25      jonathan  841: /*
                    842:  * Check that all the files in check_table are present in the
                    843:  * target root. Warn if not found.
                    844:  */
1.14      jonathan  845: int
                    846: sanity_check()
                    847: {
                    848:        int target_ok = 1;
                    849:        struct check_table *p;
                    850:
                    851:        for (p = checks; p->path; p++) {
1.54      fvdl      852:                target_ok = target_ok && check_for(p->mode, p->path);
1.14      jonathan  853:        }
                    854:        if (target_ok)
                    855:                return 0;
                    856:
                    857:        /* Uh, oh. Something's missing. */
                    858:        msg_display(MSG_badroot);
                    859:        process_menu(MENU_ok);
                    860:        return 1;
1.11      jonathan  861: }
1.32      garbled   862:
                    863: /* set reverse to 1 to default to no */
                    864: int askyesno(int reverse)
                    865: {
                    866:        WINDOW *yesnowin;
                    867:        int c, found;
                    868:
1.40      simonb    869:        yesnowin = subwin(stdscr, 5, 20, getmaxy(stdscr)/2 - 2, getmaxx(stdscr)/2 - 10);
1.41      garbled   870:        if (yesnowin == NULL) {
                    871:                fprintf(stderr, "sysinst: failed to allocate yes/no box\n");
                    872:                exit(1);
                    873:        }
1.32      garbled   874:        box(yesnowin, '*', '*');
                    875:        wmove(yesnowin, 2,2);
                    876:
                    877:        if (reverse)
                    878:                waddstr(yesnowin, "Yes or No: [N]");
                    879:        else
                    880:                waddstr(yesnowin, "Yes or No: [Y]");
                    881:
                    882:        wrefresh(yesnowin);
                    883:        while ((c = getchar())) {
                    884:                if (c == 'y' || c == 'Y') {
                    885:                        found = 1;
                    886:                        break;
                    887:                } else if (c == 'n' || c == 'N' ) {
                    888:                        found = 0;
                    889:                        break;
                    890:                } else if (c == '\n' || c == '\r') {
                    891:                        if (reverse)
                    892:                                found = 0;
                    893:                        else
                    894:                                found = 1;
                    895:                        break;
                    896:                }
                    897:        }
                    898:        wclear(yesnowin);
                    899:        wrefresh(yesnowin);
                    900:        delwin(yesnowin);
                    901:        refresh();
                    902:        return(found);
1.52      hubertf   903: }
                    904:
                    905: /*
                    906:  * Some globals to pass things back from callbacks
                    907:  */
                    908: static char zoneinfo_dir[STRSIZE];
                    909: static char *tz_selected;      /* timezonename (relative to share/zoneinfo */
                    910: static char *tz_default;       /* UTC, or whatever /etc/localtime points to */
                    911: static char tz_env[STRSIZE];
                    912:
                    913: /*
                    914:  * Callback from timezone menu
                    915:  */
                    916: static int
                    917: set_timezone_select(menudesc *m)
                    918: {
                    919:        time_t t;
                    920:
                    921:        if (m)
                    922:                tz_selected = m->opts[m->cursel].opt_name;
                    923:        snprintf(tz_env, sizeof(tz_env), "%s/%s",
                    924:                 zoneinfo_dir, tz_selected);
                    925:        setenv("TZ", tz_env, 1);
                    926:        t = time(NULL);
                    927:        msg_display(MSG_choose_timezone,
                    928:                    tz_default, tz_selected, ctime(&t), localtime(&t)->tm_zone);
                    929:        return 0;
                    930: }
                    931:
                    932: /*
                    933:  * Alarm-handler to update example-display
                    934:  */
                    935: static void
                    936: timezone_sig(int sig)
                    937: {
                    938:        set_timezone_select(NULL);
1.67.2.7  lukem     939:        alarm(60);
1.52      hubertf   940: }
                    941:
                    942: /*
                    943:  * Choose from the files in usr/share/zoneinfo and set etc/localtime
                    944:  */
                    945: int
                    946: set_timezone()
                    947: {
                    948:        char localtime_link[STRSIZE];
                    949:        char localtime_target[STRSIZE];
                    950:        int rc;
                    951:        time_t t;
                    952:        sig_t oldalrm;
                    953:        FTS *tree;
                    954:        FTSENT *entry;
                    955:        int rval;
                    956:        char *argv[2];
                    957:        int skip;
                    958:        struct stat sb;
                    959:        int nfiles, n;
                    960:        int menu_no;
                    961:        menu_ent *tz_menu;
                    962:
1.64      mrg       963:        oldalrm = signal(SIGALRM, timezone_sig);
1.52      hubertf   964:        alarm(1);
                    965:
                    966:        strncpy(zoneinfo_dir, target_expand("/usr/share/zoneinfo"), STRSIZE);
                    967:        strncpy(localtime_link, target_expand("/etc/localtime"), STRSIZE);
                    968:
                    969:        /* Add sanity check that /mnt/usr/share/zoneinfo contains
                    970:         * something useful */
                    971:
                    972:        rc = readlink(localtime_link, localtime_target,
                    973:                      sizeof(localtime_target));
                    974:        if (rc < 0) {
1.53      hubertf   975:                /* error, default to UTC */
                    976:                tz_default = "UTC";
                    977:        } else {
                    978:                localtime_target[rc] = '\0';
                    979:                tz_default = strchr(strstr(localtime_target, "zoneinfo"), '/')+1;
1.52      hubertf   980:        }
                    981:
                    982:        tz_selected=tz_default;
                    983:        snprintf(tz_env, sizeof(tz_env), "%s/%s",
                    984:                 zoneinfo_dir, tz_selected);
                    985:        setenv("TZ", tz_env, 1);
                    986:        t = time(NULL);
                    987:        msg_display(MSG_choose_timezone,
                    988:                    tz_default, tz_selected, ctime(&t), localtime(&t)->tm_zone);
                    989:
                    990:        skip = strlen(zoneinfo_dir);
                    991:        argv[0] = zoneinfo_dir;
                    992:        argv[1] = NULL;
                    993:        if (!(tree = fts_open(argv, FTS_LOGICAL, NULL))) {
1.53      hubertf   994:                return 1;       /* error - skip timezone setting */
1.52      hubertf   995:        }
                    996:        for (nfiles = 0; (entry = fts_read(tree)) != NULL;) {
                    997:                stat(entry->fts_accpath, &sb);
                    998:                if (S_ISREG(sb.st_mode))
                    999:                        nfiles++;
                   1000:        }
                   1001:        if (errno) {
1.53      hubertf  1002:                return 1;       /* error - skip timezone setting */
1.52      hubertf  1003:        }
                   1004:        (void)fts_close(tree);
                   1005:
                   1006:        tz_menu = malloc(nfiles * sizeof(struct menu_ent));
                   1007:        if (tz_menu == NULL) {
1.53      hubertf  1008:                return 1;       /* error - skip timezone setting */
1.52      hubertf  1009:        }
                   1010:
                   1011:        if (!(tree = fts_open(argv, FTS_LOGICAL, NULL))) {
1.53      hubertf  1012:                return 1;       /* error - skip timezone setting */
1.52      hubertf  1013:        }
1.64      mrg      1014:        n = 0;
                   1015:        for (rval = 0; (entry = fts_read(tree)) != NULL; ) {
1.52      hubertf  1016:                stat(entry->fts_accpath, &sb);
                   1017:                if (S_ISREG(sb.st_mode)) {
                   1018:                        tz_menu[n].opt_name = strdup(entry->fts_accpath+skip+1);
                   1019:                        tz_menu[n].opt_menu = OPT_NOMENU;
                   1020:                        tz_menu[n].opt_flags = 0;
                   1021:                        tz_menu[n].opt_action = set_timezone_select;
                   1022:
                   1023:                        n++;
                   1024:                }
                   1025:        }
                   1026:        if (errno) {
1.53      hubertf  1027:                return 1;       /* error - skip timezone setting */
1.52      hubertf  1028:        }
                   1029:        (void)fts_close(tree);
                   1030:
                   1031:        menu_no = new_menu(NULL, tz_menu, nfiles, 23, 9,
                   1032:                           12, 32, MC_SCROLL|MC_NOSHORTCUT, NULL, NULL,
                   1033:                           "\nPlease consult the install documents.");
                   1034:        if (menu_no < 0) {
1.53      hubertf  1035:                return 1;       /* error - skip timezone setting */
1.52      hubertf  1036:        }
                   1037:        process_menu(menu_no);
                   1038:
                   1039:        free_menu(menu_no);
                   1040:        for(n=0; n < nfiles; n++)
                   1041:                free(tz_menu[n].opt_name);
                   1042:        free(tz_menu);
                   1043:
                   1044:        signal(SIGALRM, SIG_IGN);
                   1045:
                   1046:        snprintf(localtime_target, sizeof(localtime_target),
                   1047:                 "/usr/share/zoneinfo/%s", tz_selected);
                   1048:        unlink(localtime_link);
                   1049:        symlink(localtime_target, localtime_link);
                   1050:
                   1051:        return 1;
1.66      ad       1052: }
                   1053:
                   1054: int
                   1055: set_crypt_type(void)
                   1056: {
                   1057:        FILE *pwc;
                   1058:        char *fn;
                   1059:
                   1060:        msg_display(MSG_choose_crypt);
                   1061:        process_menu(MENU_crypttype);
                   1062:        fn = strdup(target_expand("/etc/passwd.conf"));
                   1063:
1.67.2.2  lukem    1064:        switch (yesno) {
                   1065:        case 0:
                   1066:                break;
                   1067:        case 1: /* DES */
                   1068:                rename(fn, target_expand("/etc/passwd.conf.pre-sysinst"));
                   1069:                pwc = fopen(fn, "w");
                   1070:                fprintf(pwc,
                   1071:                    "default:\n"
                   1072:                    "  localcipher = old\n"
                   1073:                    "  ypcipher = old\n");
                   1074:                fclose(pwc);
                   1075:                break;
                   1076:        case 2: /* MD5 */
                   1077:                rename(fn, target_expand("/etc/passwd.conf.pre-sysinst"));
1.66      ad       1078:                pwc = fopen(fn, "w");
                   1079:                fprintf(pwc,
                   1080:                    "default:\n"
                   1081:                    "  localcipher = md5\n"
                   1082:                    "  ypcipher = md5\n");
                   1083:                fclose(pwc);
1.67.2.2  lukem    1084:                break;
1.66      ad       1085:        }
                   1086:
1.67      ad       1087:        free(fn);
1.66      ad       1088:        return (0);
1.56      fvdl     1089: }
                   1090:
                   1091: int
                   1092: set_root_password()
                   1093: {
                   1094:        msg_display(MSG_rootpw);
                   1095:        process_menu(MENU_yesno);
                   1096:        if (yesno)
                   1097:                run_prog(RUN_DISPLAY|RUN_CHROOT, NULL, "passwd -l root");
                   1098:        return 0;
1.64      mrg      1099: }
                   1100:
                   1101: void
                   1102: scripting_vfprintf(FILE *f, const char *fmt, va_list ap)
                   1103: {
                   1104:        if (f)
                   1105:                (void)vfprintf(f, fmt, ap);
                   1106:        if (scripting)
                   1107:                (void)vfprintf(script, fmt, ap);
                   1108: }
                   1109:
                   1110: void
                   1111: scripting_fprintf(FILE *f, const char *fmt, ...)
                   1112: {
                   1113:        va_list ap;
                   1114:
                   1115:        va_start(ap, fmt);
                   1116:        scripting_vfprintf(f, fmt, ap);
                   1117:        va_end(ap);
                   1118: }
                   1119:
                   1120: void
                   1121: add_rc_conf(const char *fmt, ...)
                   1122: {
                   1123:        FILE *f;
                   1124:        va_list ap;
                   1125:
                   1126:        va_start(ap, fmt);
                   1127:        f = target_fopen("/etc/rc.conf", "a");
                   1128:        if (f != 0) {
                   1129:                scripting_fprintf(NULL, "cat <<EOF >>%s/etc/rc.conf\n",
                   1130:                    target_prefix());
                   1131:                scripting_vfprintf(f, fmt, ap);
                   1132:                fclose(f);
                   1133:                scripting_fprintf(NULL, "EOF\n");
                   1134:        }
                   1135:        va_end(ap);
                   1136: }
                   1137:
                   1138: /*
                   1139:  * check that there is at least a / somewhere.
                   1140:  */
                   1141: int
                   1142: check_partitions()
                   1143: {
                   1144:        int i;
                   1145:
                   1146:        for (i = 0; i < getmaxpartitions(); i++)
                   1147:                if (PI_ISBSDFS(&bsdlabel[i]) &&
                   1148:                    fsmount[i][0] == '/' && fsmount[i][1] == '\0')
                   1149:                        return 1;
                   1150:        msg_display(MSG_no_root_fs);
                   1151:        getchar();
                   1152:        return 0;
                   1153: }
                   1154:
                   1155: void
                   1156: set_sizemultname_cyl()
                   1157: {
                   1158:
                   1159:        sizemult = dlcylsize;
                   1160:        multname = msg_string(MSG_cylname);
                   1161: }
                   1162:
                   1163: void
                   1164: set_sizemultname_meg()
                   1165: {
                   1166:
                   1167:        sizemult = MEG / sectorsize;
                   1168:        multname = msg_string(MSG_megname);
                   1169: }
                   1170:
                   1171: int
                   1172: check_lfs_progs()
                   1173: {
                   1174:
                   1175:        return (access("/sbin/dump_lfs", X_OK) == 0 &&
                   1176:                access("/sbin/fsck_lfs", X_OK) == 0 &&
                   1177:                access("/sbin/mount_lfs", X_OK) == 0 &&
                   1178:                access("/sbin/newfs_lfs", X_OK) == 0);
1.32      garbled  1179: }

CVSweb <webmaster@jp.NetBSD.org>