[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.49

1.49    ! cgd         1: /*     $NetBSD: util.c,v 1.48 1999/07/04 22:31:37 cgd Exp $    */
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.1       phil       50: #include "defs.h"
1.5       phil       51: #include "md.h"
1.1       phil       52: #include "msg_defs.h"
                     53: #include "menu_defs.h"
1.4       phil       54:
1.14      jonathan   55: /*
                     56:  * local prototypes
                     57:  */
1.29      mrg        58: struct  tarstats {
1.22      jonathan   59:        int nselected;
                     60:        int nfound;
                     61:        int nnotfound;
                     62:        int nerror;
                     63:        int nsuccess;
1.44      cgd        64:        int nskipped;
1.22      jonathan   65: } tarstats;
                     66:
1.44      cgd        67: int    extract_file __P((char *path));
1.22      jonathan   68: int    extract_dist __P((void));
1.37      bouyer     69: int    cleanup_dist __P((const char *path));
1.22      jonathan   70: int    distribution_sets_exist_p __P((const char *path));
1.14      jonathan   71: static int check_for __P((const char *type, const char *pathname));
1.4       phil       72:
1.29      mrg        73: /*
                     74:  * XXX these are WAY bogus!
                     75:  */
                     76: int
                     77: dir_exists_p(path)
                     78:        const char *path;
1.22      jonathan   79: {
                     80:        register int result;
1.29      mrg        81:
1.35      bouyer     82:        result = (run_prog(0, 0, NULL, "test -d %s", path) == 0);
1.22      jonathan   83:        return (result);
                     84: }
                     85:
1.29      mrg        86: int
                     87: file_exists_p(path)
                     88:        const char *path;
1.22      jonathan   89: {
                     90:        register int result;
1.29      mrg        91:
1.35      bouyer     92:        result = (run_prog(0, 0, NULL, "test -f %s", path) == 0);
1.22      jonathan   93:        return (result);
                     94: }
                     95:
1.29      mrg        96: int
                     97: distribution_sets_exist_p(path)
                     98:        const char *path;
1.22      jonathan   99: {
                    100:        char buf[STRSIZE];
                    101:        int result;
                    102:
                    103:        result = 1;
                    104:        snprintf(buf, STRSIZE, "%s/%s", path, "kern.tgz");
                    105:        result = result && file_exists_p(buf);
                    106:
                    107:        snprintf(buf, STRSIZE, "%s/%s", path, "etc.tgz");
                    108:        result = result && file_exists_p(buf);
                    109:
                    110:        return(result);
                    111: }
                    112:
                    113:
1.29      mrg       114: void
                    115: get_ramsize()
1.4       phil      116: {
1.29      mrg       117:        long len = sizeof(long);
1.4       phil      118:        int mib[2] = {CTL_HW, HW_PHYSMEM};
                    119:
                    120:        sysctl(mib, 2, (void *)&ramsize, (size_t *)&len, NULL, 0);
                    121:
                    122:        /* Find out how many Megs ... round up. */
                    123:        rammb = (ramsize + MEG - 1) / MEG;
                    124: }
                    125:
1.1       phil      126: static int asked = 0;
                    127:
1.29      mrg       128: void
                    129: ask_sizemult()
1.1       phil      130: {
1.29      mrg       131:
1.1       phil      132:        if (!asked) {
1.29      mrg       133:                msg_display(MSG_sizechoice, dlcylsize);
                    134:                process_menu(MENU_sizechoice);
1.1       phil      135:        }
                    136:        asked = 1;
1.9       phil      137: }
                    138:
1.29      mrg       139: void
                    140: reask_sizemult()
1.9       phil      141: {
1.29      mrg       142:
1.9       phil      143:        asked = 0;
1.29      mrg       144:        ask_sizemult();
1.1       phil      145: }
                    146:
1.29      mrg       147: void
                    148: run_makedev()
1.3       phil      149: {
1.22      jonathan  150:        char *owd;
                    151:
1.39      bouyer    152:        wclear(stdscr);
                    153:        wrefresh(stdscr);
1.29      mrg       154:        msg_display(MSG_makedev);
1.5       phil      155:        sleep (1);
1.14      jonathan  156:
1.29      mrg       157:        owd = getcwd(NULL,0);
1.22      jonathan  158:
1.14      jonathan  159:        /* make /dev, in case the user  didn't extract it. */
                    160:        make_target_dir("/dev");
1.10      jonathan  161:        target_chdir_or_die("/dev");
1.35      bouyer    162:        run_prog(0, 0, NULL, "/bin/sh MAKEDEV all");
1.22      jonathan  163:
                    164:        chdir(owd);
                    165:        free(owd);
1.5       phil      166: }
                    167:
                    168:
1.29      mrg       169: /*
                    170:  * Load files from floppy.  Requires a /mnt2 directory for mounting them.
                    171:  */
                    172: int
                    173: get_via_floppy()
1.5       phil      174: {
                    175:        char distname[STRSIZE];
                    176:        char fddev[STRSIZE] = "/dev/fd0a";
                    177:        char fname[STRSIZE];
                    178:        char fullname[STRSIZE];
1.34      garbled   179:        char catcmd[STRSIZE];
1.7       phil      180:        distinfo *list;
1.5       phil      181:        char post[4];
                    182:        int  mounted = 0;
1.8       phil      183:        int  first;
1.5       phil      184:        struct stat sb;
                    185:
1.29      mrg       186:        cd_dist_dir("unloading from floppy");
1.7       phil      187:
1.29      mrg       188:        msg_prompt_add(MSG_fddev, fddev, fddev, STRSIZE);
1.5       phil      189:
                    190:        list = dist_list;
1.7       phil      191:        while (list->name) {
1.29      mrg       192:                strcpy(post, ".aa");
                    193:                snprintf(distname, STRSIZE, "%s%s", list->name, dist_postfix);
1.8       phil      194:                while (list->getit && strcmp(&post[1],list->fdlast) <= 0) {
1.29      mrg       195:                        snprintf(fname, STRSIZE, "%s%s", list->name, post);
                    196:                        snprintf(fullname, STRSIZE, "/mnt2/%s", fname);
1.8       phil      197:                        first = 1;
1.5       phil      198:                        while (!mounted || stat(fullname, &sb)) {
1.8       phil      199:                                if (mounted)
1.35      bouyer    200:                                  run_prog(0, 0, NULL, "/sbin/umount /mnt2");
1.8       phil      201:                                if (first)
1.29      mrg       202:                                        msg_display(MSG_fdmount, fname);
1.8       phil      203:                                else
1.29      mrg       204:                                        msg_display(MSG_fdnotfound, fname);
                    205:                                process_menu(MENU_fdok);
1.8       phil      206:                                if (!yesno)
                    207:                                        return 0;
1.35      bouyer    208:                                while (run_prog(0, 0, NULL,
                    209:                                    "/sbin/mount -r -t %s %s /mnt2",
1.29      mrg       210:                                    fdtype, fddev)) {
                    211:                                        msg_display(MSG_fdremount, fname);
                    212:                                        process_menu(MENU_fdremount);
1.5       phil      213:                                        if (!yesno)
                    214:                                                return 0;
                    215:                                }
                    216:                                mounted = 1;
1.8       phil      217:                                first = 0;
1.5       phil      218:                        }
1.34      garbled   219:                        sprintf(catcmd, "/bin/cat %s >> %s",
                    220:                                fullname, distname);
                    221:                        if (logging)
                    222:                                (void)fprintf(log, "%s\n", catcmd);
                    223:                        if (scripting)
                    224:                                (void)fprintf(script, "%s\n", catcmd);
                    225:                        do_system(catcmd);
1.8       phil      226:                        if (post[2] < 'z')
                    227:                                post[2]++;
1.5       phil      228:                        else
1.29      mrg       229:                                post[2] = 'a', post[1]++;
1.5       phil      230:                }
1.35      bouyer    231:                run_prog(0, 0, NULL, "/sbin/umount /mnt2");
1.5       phil      232:                mounted = 0;
                    233:                list++;
                    234:        }
                    235: #ifndef DEBUG
1.10      jonathan  236:        chdir("/");     /* back to current real root */
1.5       phil      237: #endif
1.6       phil      238:        return 1;
                    239: }
                    240:
1.29      mrg       241: /*
                    242:  * Get from a CDROM distribution.
                    243:  */
1.6       phil      244: int
1.29      mrg       245: get_via_cdrom()
1.6       phil      246: {
1.22      jonathan  247:        char tmpdir[STRSIZE];
                    248:
1.29      mrg       249:        /*
                    250:         * Fill in final default path, similar to ftp path
                    251:         * because we expect the CDROM structure to be the
                    252:         * same as the ftp site.
                    253:         */
                    254:        strncat(cdrom_dir, machine, STRSIZE - strlen(cdrom_dir));
                    255:        strncat(cdrom_dir, ftp_prefix, STRSIZE - strlen(cdrom_dir));
1.28      fvdl      256:
                    257:        /* Get CD-rom device name and path within CD-rom */
1.29      mrg       258:        process_menu(MENU_cdromsource);
1.6       phil      259:
1.22      jonathan  260: again:
1.35      bouyer    261:        run_prog(0, 0, NULL, "/sbin/umount /mnt2");
1.22      jonathan  262:
1.6       phil      263:        /* Mount it */
1.35      bouyer    264:        if (run_prog(0, 0, NULL,
                    265:            "/sbin/mount -rt cd9660 /dev/%sa /mnt2", cdrom_dev)) {
1.22      jonathan  266:                msg_display(MSG_badsetdir, cdrom_dev);
1.29      mrg       267:                process_menu(MENU_cdrombadmount);
1.6       phil      268:                if (!yesno)
                    269:                        return 0;
1.22      jonathan  270:                if (!ignorerror)
                    271:                        goto again;
                    272:        }
                    273:
                    274:        snprintf(tmpdir, STRSIZE, "%s/%s", "/mnt2", cdrom_dir);
                    275:
                    276:        /* Verify distribution files exist.  */
                    277:        if (distribution_sets_exist_p(tmpdir) == 0) {
                    278:                msg_display(MSG_badsetdir, tmpdir);
1.29      mrg       279:                process_menu(MENU_cdrombadmount);
1.22      jonathan  280:                if (!yesno)
                    281:                        return (0);
                    282:                if (!ignorerror)
                    283:                        goto again;
1.6       phil      284:        }
                    285:
                    286:        /* return location, don't clean... */
1.22      jonathan  287:        strncpy(ext_dir, tmpdir, STRSIZE);
1.6       phil      288:        clean_dist_dir = 0;
                    289:        mnt2_mounted = 1;
1.5       phil      290:        return 1;
1.7       phil      291: }
                    292:
1.22      jonathan  293:
                    294: /*
                    295:  * Get from a pathname inside an unmounted local filesystem
                    296:  * (e.g., where sets were preloaded onto a local DOS partition)
                    297:  */
1.29      mrg       298: int
                    299: get_via_localfs()
1.16      mhitch    300: {
1.22      jonathan  301:        char tmpdir[STRSIZE];
                    302:
1.16      mhitch    303:        /* Get device, filesystem, and filepath */
                    304:        process_menu (MENU_localfssource);
                    305:
1.22      jonathan  306: again:
1.35      bouyer    307:        run_prog(0, 0, NULL, "/sbin/umount /mnt2");
1.22      jonathan  308:
1.16      mhitch    309:        /* Mount it */
1.35      bouyer    310:        if (run_prog(0, 0, NULL, "/sbin/mount -rt %s /dev/%s /mnt2",
                    311:            localfs_fs, localfs_dev)) {
1.22      jonathan  312:
1.29      mrg       313:                msg_display(MSG_localfsbadmount, localfs_dir, localfs_dev);
                    314:                process_menu(MENU_localfsbadmount);
1.16      mhitch    315:                if (!yesno)
                    316:                        return 0;
1.22      jonathan  317:                if (!ignorerror)
1.29      mrg       318:                        goto again;
1.22      jonathan  319:        }
                    320:
                    321:        snprintf(tmpdir, STRSIZE, "%s/%s", "/mnt2", localfs_dir);
                    322:
                    323:        /* Verify distribution files exist.  */
                    324:        if (distribution_sets_exist_p(tmpdir) == 0) {
                    325:                msg_display(MSG_badsetdir, tmpdir);
1.29      mrg       326:                process_menu(MENU_localfsbadmount);
1.22      jonathan  327:                if (!yesno)
                    328:                        return 0;
                    329:                if (!ignorerror)
                    330:                        goto again;
1.16      mhitch    331:        }
                    332:
                    333:        /* return location, don't clean... */
1.22      jonathan  334:        strncpy(ext_dir, tmpdir, STRSIZE);
1.16      mhitch    335:        clean_dist_dir = 0;
                    336:        mnt2_mounted = 1;
                    337:        return 1;
                    338: }
1.7       phil      339:
1.29      mrg       340: /*
                    341:  * Get from an already-mounted pathname.
                    342:  */
1.22      jonathan  343:
                    344: int get_via_localdir(void)
                    345: {
                    346:
                    347:        /* Get device, filesystem, and filepath */
1.29      mrg       348:        process_menu(MENU_localdirsource);
1.22      jonathan  349:
                    350: again:
                    351:        /* Complain if not a directory */
                    352:        if (dir_exists_p(localfs_dir) == 0) {
                    353:
1.29      mrg       354:                msg_display(MSG_badlocalsetdir, localfs_dir);
                    355:                process_menu(MENU_localdirbad);
1.22      jonathan  356:                if (!yesno)
                    357:                        return (0);
                    358:                if (!ignorerror)
                    359:                        goto again;
                    360:        }
                    361:
                    362:        /* Verify distribution files exist.  */
                    363:        if (distribution_sets_exist_p(localfs_dir) == 0) {
                    364:                msg_display(MSG_badsetdir, localfs_dir);
1.29      mrg       365:                process_menu(MENU_localdirbad);
1.22      jonathan  366:                if (!yesno)
                    367:                        return (0);
                    368:                if (!ignorerror)
                    369:                        goto again;
                    370:        }
                    371:
                    372:        /* return location, don't clean... */
1.29      mrg       373:        strncpy(ext_dir, localfs_dir, STRSIZE);
1.22      jonathan  374:        clean_dist_dir = 0;
                    375:        mnt2_mounted = 0;
                    376:        return 1;
                    377: }
                    378:
                    379:
1.29      mrg       380: void
                    381: cd_dist_dir(forwhat)
                    382:        char *forwhat;
1.7       phil      383: {
1.19      phil      384:        char *cwd;
                    385:
1.10      jonathan  386:        /* ask user for the mountpoint. */
1.29      mrg       387:        msg_prompt(MSG_distdir, dist_dir, dist_dir, STRSIZE, forwhat);
1.10      jonathan  388:
                    389:        /* make sure the directory exists. */
                    390:        make_target_dir(dist_dir);
1.7       phil      391:
                    392:        clean_dist_dir = 1;
1.10      jonathan  393:        target_chdir_or_die(dist_dir);
1.19      phil      394:
                    395:        /* Set ext_dir for absolute path. */
1.29      mrg       396:        cwd = getcwd(NULL,0);
                    397:        strncpy(ext_dir, cwd, STRSIZE);
1.19      phil      398:        free (cwd);
1.7       phil      399: }
                    400:
1.10      jonathan  401:
1.29      mrg       402: /*
                    403:  * Support for custom distribution fetches / unpacks.
                    404:  */
                    405: void
                    406: toggle_getit(num)
                    407:        int num;
                    408: {
1.7       phil      409:
                    410:        dist_list[num].getit ^= 1;
                    411: }
                    412:
1.29      mrg       413: void
                    414: show_cur_distsets()
1.7       phil      415: {
                    416:        distinfo *list;
                    417:
1.29      mrg       418:        msg_display(MSG_cur_distsets);
1.48      cgd       419:        msg_table_add(MSG_cur_distsets_header);
1.7       phil      420:        list = dist_list;
                    421:        while (list->name) {
1.48      cgd       422:                msg_table_add(MSG_cur_distsets_row, list->desc,
1.29      mrg       423:                    list->getit ? msg_string(MSG_yes) : msg_string(MSG_no));
1.7       phil      424:                list++;
                    425:        }
1.1       phil      426: }
1.10      jonathan  427:
1.12      phil      428: /* Do we want a verbose extract? */
                    429: static int verbose = -1;
                    430:
                    431: void
1.29      mrg       432: ask_verbose_dist()
1.12      phil      433: {
1.29      mrg       434:
1.12      phil      435:        if (verbose < 0) {
1.29      mrg       436:                msg_display(MSG_verboseextract);
                    437:                process_menu(MENU_noyes);
1.12      phil      438:                verbose = yesno;
1.36      bouyer    439:                wclear(stdscr);
                    440:                wrefresh(stdscr);
1.12      phil      441:        }
                    442: }
                    443:
1.44      cgd       444: int
1.29      mrg       445: extract_file(path)
                    446:        char *path;
1.12      phil      447: {
                    448:        char *owd;
1.44      cgd       449:        int   tarexit, rv;
1.12      phil      450:
                    451:        owd = getcwd (NULL,0);
                    452:
1.22      jonathan  453:        /* check tarfile exists */
                    454:        if (!file_exists_p(path)) {
                    455:                tarstats.nnotfound++;
1.44      cgd       456:
                    457:                msg_display(MSG_notarfile, path);
                    458:                process_menu(MENU_noyes);
                    459:                return (yesno == 0);
1.22      jonathan  460:        }
                    461:
                    462:        tarstats.nfound++;
1.14      jonathan  463:        /* cd to the target root. */
1.12      phil      464:        target_chdir_or_die("/");
                    465:
1.14      jonathan  466:        /* now extract set files files into "./". */
1.35      bouyer    467:        tarexit = run_prog(0, 1, NULL,
                    468:            "pax -zr%spe -f %s", verbose ? "v" : "", path);
1.22      jonathan  469:
1.17      phil      470:        /* Check tarexit for errors and give warning. */
1.22      jonathan  471:        if (tarexit) {
                    472:                tarstats.nerror++;
1.44      cgd       473:
                    474:                msg_display(MSG_tarerror, path);
                    475:                process_menu(MENU_noyes);
                    476:                rv = (yesno == 0);
1.22      jonathan  477:        } else {
                    478:                tarstats.nsuccess++;
1.44      cgd       479:                rv = 0;
1.22      jonathan  480:        }
                    481:
1.29      mrg       482:        chdir(owd);
                    483:        free(owd);
1.44      cgd       484:
                    485:        return (rv);
1.12      phil      486: }
                    487:
1.19      phil      488:
1.29      mrg       489: /*
1.37      bouyer    490:  * Extract_dist **REQUIRES** an absolute path in ext_dir.  Any code
1.19      phil      491:  * that sets up dist_dir for use by extract_dist needs to put in the
                    492:  * full path name to the directory.
                    493:  */
                    494:
1.22      jonathan  495: int
1.29      mrg       496: extract_dist()
1.12      phil      497: {
                    498:        char distname[STRSIZE];
                    499:        char fname[STRSIZE];
                    500:        distinfo *list;
1.44      cgd       501:        int punt;
1.12      phil      502:
1.22      jonathan  503:        /* reset failure/success counters */
1.31      perry     504:        memset(&tarstats, 0, sizeof(tarstats));
1.22      jonathan  505:
1.32      garbled   506:        /*endwin();*/
1.44      cgd       507:        for (punt = 0, list = dist_list; list->name != NULL; list++) {
1.15      phil      508:                if (list->getit) {
1.22      jonathan  509:                        tarstats.nselected++;
1.44      cgd       510:                        if (punt) {
                    511:                                tarstats.nskipped++;
                    512:                                continue;
                    513:                        }
1.37      bouyer    514:                        if (cleanup_dist(list->name) == 0) {
                    515:                                msg_display(MSG_cleanup_warn);
                    516:                                process_menu(MENU_ok);
                    517:                        }
1.29      mrg       518:                        (void)snprintf(distname, STRSIZE, "%s%s", list->name,
                    519:                            dist_postfix);
                    520:                        (void)snprintf(fname, STRSIZE, "%s/%s", ext_dir,
                    521:                            distname);
1.44      cgd       522:
                    523:                        /* if extraction failed and user aborted, punt. */
                    524:                        punt = extract_file(fname);
1.15      phil      525:                }
1.12      phil      526:        }
1.22      jonathan  527:
1.43      cgd       528:        puts(CL);               /* XXX */
                    529:        wclear(stdscr);
1.17      phil      530:        wrefresh(stdscr);
1.22      jonathan  531:
                    532:        if (tarstats.nerror == 0 && tarstats.nsuccess == tarstats.nselected) {
1.29      mrg       533:                msg_display(MSG_endtarok);
                    534:                process_menu(MENU_ok);
1.22      jonathan  535:                return 0;
                    536:        } else {
                    537:                /* We encountered  errors. Let the user know. */
                    538:                msg_display(MSG_endtar,
1.44      cgd       539:                    tarstats.nselected, tarstats.nnotfound, tarstats.nskipped,
1.22      jonathan  540:                    tarstats.nfound, tarstats.nsuccess, tarstats.nerror);
1.29      mrg       541:                process_menu(MENU_ok);
1.22      jonathan  542:                return 1;
                    543:        }
1.12      phil      544: }
                    545:
1.11      jonathan  546: /*
1.37      bouyer    547:  * Do pre-extract cleanup for set 'name':
                    548:  * open a file named '/dist/<name>_obsolete file', which contain a list of
                    549:  * files to kill from the target. For each file, test if it is present on
                    550:  * the target. Then display the list of files which will be removed,
                    551:  * ask user for confirmation, and process.
                    552:  * Non-empty directories will be renaned to <directory.old>.
                    553:  */
                    554:
                    555: /* definition for a list of files. */
                    556: struct filelist {
                    557:        struct filelist *next;
                    558:        char name[MAXPATHLEN];
                    559:        mode_t type;
                    560: };
                    561:
                    562: int
                    563: cleanup_dist(name)
                    564:        const char *name;
                    565: {
                    566:        char file_path[MAXPATHLEN];
                    567:        char file_name[MAXPATHLEN];
                    568:        FILE *list_file;
                    569:        struct filelist *head = NULL;
                    570:        struct filelist *current;
                    571:        int saved_errno;
                    572:        struct stat st;
                    573:        int retval = 1;
                    574:        int needok = 0;
                    575:
                    576:        snprintf(file_path, MAXPATHLEN, "/dist/%s_obsolete", name);
                    577:        list_file = fopen(file_path, "r");
                    578:        if (list_file == NULL) {
                    579:                saved_errno = errno;
                    580:                if (logging)
                    581:                        fprintf(log, "Open of %s failed: %s\n", file_path,
                    582:                            strerror(saved_errno));
                    583:                if (saved_errno == ENOENT)
                    584:                        return 1;
                    585:                msg_display_add(MSG_openfail, name, strerror(saved_errno));
                    586:                process_menu(MENU_ok);
                    587:                return 0;
                    588:        }
                    589:        while (fgets(file_name, MAXPATHLEN, list_file)) {
                    590:                /* ignore lines that don't begin with '/' */
                    591:                if (file_name[0] != '/')
                    592:                        continue;
                    593:                /* Remove trailing \n if any */
                    594:                if (file_name[strlen(file_name)-1] == '\n')
                    595:                        file_name[strlen(file_name)-1] = '\0';
                    596:                snprintf(file_path, MAXPATHLEN, "%s%s", target_prefix(),
                    597:                    file_name);
                    598:                if (lstat(file_path, &st) != 0) {
                    599:                        saved_errno = errno;
                    600:                        if (logging)
                    601:                                fprintf(log, "stat() of %s failed: %s\n",
                    602:                                    file_path, strerror(saved_errno));
                    603:                        if (saved_errno == ENOENT)
                    604:                                continue;
                    605:                        msg_display_add(MSG_statfail, file_path,
                    606:                            strerror(saved_errno));
                    607:                        process_menu(MENU_ok);
                    608:                        return 0;
                    609:                }
                    610:                if (head == NULL) {
                    611:                        head = current = malloc(sizeof(struct filelist));
                    612:                        if (head == NULL) {
                    613:                                fprintf(stderr, "out of memory\n");
                    614:                                exit(1);
                    615:                        }
                    616:                } else {
                    617:                        current->next = malloc(sizeof(struct filelist));
                    618:                        if (head == NULL) {
                    619:                                fprintf(stderr, "out of memory\n");
                    620:                                exit(1);
                    621:                        }
                    622:                        current = current->next;
                    623:                }
                    624:                current->next = NULL;
                    625:                snprintf(current->name, MAXPATHLEN, "%s", file_path);
                    626:                current->type = st.st_mode & S_IFMT;
                    627:                if (logging)
                    628:                        fprintf(log, "Adding file %s, type %d to list of "
                    629:                            "obsolete file\n", current->name, current->type);
                    630:        }
                    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;
                    659:                        if (logging)
                    660:                                fprintf(log, "rm %s failed: %s\n",
                    661:                                    current->name, strerror(saved_errno));
                    662:                        msg_display_add(MSG_unlink_fail, current->name,
                    663:                            strerror(saved_errno));
                    664:                        retval = 0;
                    665:                        needok = 1;
                    666:                }
                    667:
                    668:        }
                    669:        /* now dirs */
                    670:        for (current = head; current != NULL; current = current->next) {
                    671:                if (current->type != S_IFDIR)
                    672:                        continue;
                    673:                if (rmdir(current->name) == 0) {
                    674:                        if (scripting)
                    675:                                (void)fprintf(script, "rmdir %s\n",
                    676:                                    current->name);
                    677:                        continue;
                    678:                }
                    679:                saved_errno = errno;
                    680:                if (saved_errno == ENOTEMPTY) {
                    681:                        if (logging)
                    682:                                fprintf(log, "dir %s not empty, "
                    683:                                    "trying to rename to %s.old\n",
                    684:                                    current->name, current->name);
                    685:                        snprintf(file_path, MAXPATHLEN,
                    686:                            "%s.old", current->name);
                    687:                        if (scripting)
                    688:                                (void)fprintf(script, "mv %s %s\n",
                    689:                                    current->name, file_path);
                    690:                        needok = 1;
                    691:                        if (rename(current->name, file_path) != 0) {
                    692:                                saved_errno = errno;
                    693:                                if (logging)
                    694:                                        fprintf(log, "mv %s %s failed: %s\n",
                    695:                                            current->name, file_path,
                    696:                                            strerror(saved_errno));
                    697:                                msg_display_add(MSG_rename_fail, current->name,
                    698:                                    file_path, strerror(errno));
                    699:                                 retval = 0;
                    700:                        }
                    701:                        msg_display_add(MSG_renamed_dir, current->name,
                    702:                            file_path);
                    703:                } else { /* rmdir error */
                    704:                        if (logging)
                    705:                                fprintf(log, "rm %s failed: %s\n",
                    706:                                    current->name, strerror(saved_errno));
                    707:                        msg_display_add(MSG_unlink_fail, current->name,
                    708:                            strerror(saved_errno));
                    709:                        retval = 0;
                    710:                        needok = 1;
                    711:                }
                    712:        }
                    713:        if (needok)
                    714:                process_menu(MENU_ok);
                    715:        return retval;
                    716: }
                    717:
                    718: /*
1.29      mrg       719:  * Get and unpack the distribution.
                    720:  * show success_msg if installation completes. Otherwise,,
                    721:  * show failure_msg and wait for the user to ack it before continuing.
1.11      jonathan  722:  * success_msg and failure_msg must both be 0-adic messages.
                    723:  */
1.45      cgd       724: int
1.29      mrg       725: get_and_unpack_sets(success_msg, failure_msg)
1.47      cgd       726:        msg success_msg;
                    727:        msg failure_msg;
1.11      jonathan  728: {
1.29      mrg       729:
1.20      jonathan  730:        /* Ensure mountpoint for distribution files exists in current root. */
1.32      garbled   731:        (void) mkdir("/mnt2", S_IRWXU| S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
                    732:        if (scripting)
                    733:                (void)fprintf(script, "mkdir /mnt2\nchmod 755 /mnt2\n");
1.20      jonathan  734:
1.26      phil      735:        /* Find out which files to "get" if we get files. */
1.37      bouyer    736:        wclear(stdscr);
                    737:        wrefresh(stdscr);
1.29      mrg       738:        process_menu(MENU_distset);
1.26      phil      739:
1.37      bouyer    740:        /* ask user whether to do normal or verbose extraction */
                    741:        ask_verbose_dist();
                    742:
1.11      jonathan  743:        /* Get the distribution files */
1.46      cgd       744:        do {
                    745:                got_dist = 0;
                    746:                process_menu(MENU_distmedium);
                    747:        } while (got_dist == -1);
1.26      phil      748:
1.11      jonathan  749:        if (nodist)
1.45      cgd       750:                return 1;
1.20      jonathan  751:
1.22      jonathan  752:        if (got_dist) {
1.11      jonathan  753:
1.22      jonathan  754:                /* Extract the distribution, abort on errors. */
1.45      cgd       755:                if (extract_dist())
                    756:                        return 1;
1.11      jonathan  757:
                    758:                /* Configure the system */
1.29      mrg       759:                run_makedev();
1.11      jonathan  760:
                    761:                /* Other configuration. */
                    762:                mnt_net_config();
                    763:
1.19      phil      764:                /* Clean up dist dir (use absolute path name) */
1.11      jonathan  765:                if (clean_dist_dir)
1.35      bouyer    766:                        run_prog(0, 0, NULL, "/bin/rm -rf %s", ext_dir);
1.11      jonathan  767:
                    768:                /* Mounted dist dir? */
                    769:                if (mnt2_mounted)
1.35      bouyer    770:                        run_prog(0, 0, NULL, "/sbin/umount /mnt2");
1.14      jonathan  771:
1.29      mrg       772:                /* Install/Upgrade complete ... reboot or exit to script */
                    773:                msg_display(success_msg);
                    774:                process_menu(MENU_ok);
1.45      cgd       775:                return 0;
1.22      jonathan  776:        }
                    777:
1.29      mrg       778:        msg_display(failure_msg);
                    779:        process_menu(MENU_ok);
1.45      cgd       780:        return 1;
1.14      jonathan  781: }
1.22      jonathan  782:
                    783:
1.14      jonathan  784:
                    785: /*
                    786:  * Do a quick sanity check that  the target can reboot.
                    787:  * return 1 if everything OK, 0 if there is a problem.
                    788:  * Uses a table of files we expect to find after a base install/upgrade.
                    789:  */
                    790:
                    791: /* test flag and pathname to check for after unpacking. */
                    792: struct check_table { const char *testarg; const char *path;} checks[] = {
                    793:   { "-f", "/netbsd" },
1.25      jonathan  794:   { "-d", "/etc" },
1.14      jonathan  795:   { "-f", "/etc/fstab" },
                    796:   { "-f", "/sbin/init" },
                    797:   { "-f", "/bin/sh" },
1.20      jonathan  798:   { "-f", "/etc/rc" },
                    799:   { "-f", "/etc/rc.subr" },
                    800:   { "-f", "/etc/rc.conf" },
1.14      jonathan  801:   { "-d" "/dev" },
                    802:   { "-c", "/dev/console" },
                    803: /* XXX check for rootdev in target /dev? */
                    804:   { "-f", "/etc/fstab" },
                    805:   { "-f", "/sbin/fsck" },
                    806:   { "-f", "/sbin/fsck_ffs" },
                    807:   { "-f", "/sbin/mount" },
                    808:   { "-f", "/sbin/mount_ffs" },
                    809:   { "-f", "/sbin/mount_nfs" },
1.20      jonathan  810: #if defined(DEBUG) || defined(DEBUG_CHECK)
                    811:   { "-f", "/foo/bar" },                /* bad entry to exercise warning */
1.14      jonathan  812: #endif
                    813:   { 0, 0 }
                    814:
                    815: };
                    816:
                    817: /*
                    818:  * Check target for a single file.
                    819:  */
1.29      mrg       820: static int
                    821: check_for(type, pathname)
                    822:        const char *type;
                    823:        const char *pathname;
1.14      jonathan  824: {
1.18      jonathan  825:        int found;
1.14      jonathan  826:
1.18      jonathan  827:        found = (target_test(type, pathname) == 0);
                    828:        if (found == 0)
1.14      jonathan  829:                msg_display(MSG_rootmissing, pathname);
1.18      jonathan  830:        return found;
1.14      jonathan  831: }
                    832:
1.25      jonathan  833: /*
                    834:  * Check that all the files in check_table are present in the
                    835:  * target root. Warn if not found.
                    836:  */
1.14      jonathan  837: int
                    838: sanity_check()
                    839: {
                    840:        int target_ok = 1;
                    841:        struct check_table *p;
                    842:
                    843:        for (p = checks; p->path; p++) {
                    844:                target_ok = target_ok && check_for(p->testarg, p->path);
                    845:        }
                    846:        if (target_ok)
                    847:                return 0;
                    848:
                    849:        /* Uh, oh. Something's missing. */
                    850:        msg_display(MSG_badroot);
                    851:        process_menu(MENU_ok);
                    852:        return 1;
1.11      jonathan  853: }
1.32      garbled   854:
                    855: /* set reverse to 1 to default to no */
                    856: int askyesno(int reverse)
                    857: {
                    858:        WINDOW *yesnowin;
                    859:        int c, found;
                    860:
1.40      simonb    861:        yesnowin = subwin(stdscr, 5, 20, getmaxy(stdscr)/2 - 2, getmaxx(stdscr)/2 - 10);
1.41      garbled   862:        if (yesnowin == NULL) {
                    863:                fprintf(stderr, "sysinst: failed to allocate yes/no box\n");
                    864:                exit(1);
                    865:        }
1.32      garbled   866:        box(yesnowin, '*', '*');
                    867:        wmove(yesnowin, 2,2);
                    868:
                    869:        if (reverse)
                    870:                waddstr(yesnowin, "Yes or No: [N]");
                    871:        else
                    872:                waddstr(yesnowin, "Yes or No: [Y]");
                    873:
                    874:        wrefresh(yesnowin);
                    875:        while ((c = getchar())) {
                    876:                if (c == 'y' || c == 'Y') {
                    877:                        found = 1;
                    878:                        break;
                    879:                } else if (c == 'n' || c == 'N' ) {
                    880:                        found = 0;
                    881:                        break;
                    882:                } else if (c == '\n' || c == '\r') {
                    883:                        if (reverse)
                    884:                                found = 0;
                    885:                        else
                    886:                                found = 1;
                    887:                        break;
                    888:                }
                    889:        }
                    890:        wclear(yesnowin);
                    891:        wrefresh(yesnowin);
                    892:        delwin(yesnowin);
                    893:        refresh();
                    894:        return(found);
                    895: }

CVSweb <webmaster@jp.NetBSD.org>