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

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

CVSweb <webmaster@jp.NetBSD.org>