Annotation of coherent/f/tmp/install/build.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * build.c
                      3:  * 07/01/93    COH 386 release
                      4:  *
                      5:  * Build (install) COHERENT on a system, part 1.
                      6:  * The second part of the install procedure is in install.c.
                      7:  * Uses common routines in build0.c,
                      8:  * serial number checking in numtab.c and serialno.c.
                      9:  * Requires floating point output: cc build.c build0.c numtab.c serialno.c -f
                     10:  * Usage: build [ -dv ]
                     11:  * Options:
                     12:  *     -d      Debug, echo commands without executing
                     13:  *     -u      Update, rather than full installation
                     14:  *     -v      Verbose
                     15:  *
                     16:  * In addition to the files necessary to run the single user system
                     17:  * (/coherent, /etc/init, /bin/sh, /dev/console, /dev/null, etc.),
                     18:  * the build disk from which this program runs must contain:
                     19:  *     In /bin:        chgrp, chown, cpdir, date, echo, ln, mkdir, mv, rm, touch
                     20:  *     In /conf:       boot, mboot, patch, upd_suppress, upd_save
                     21:  *     In /dev:        at[01][abcdx], rat[01][abcd]
                     22:  *     In /etc:        ATclock, badscan, fdisk, mkdev, mkfs, mount, umount
                     23:  * It must also contain directories /mnt and /tmp.
                     24:  * This program runs from a write-protected floppy-disk-based COHERENT
                     25:  * boot disk, so it writes only to directory /tmp (mounted on a RAM disk).
                     26:  */
                     27: 
                     28: #include <stdio.h>
                     29: #include <canon.h>
                     30: #include <string.h>
                     31: #include <time.h>
                     32: #include <unistd.h>
                     33: #include <sys/devices.h>
                     34: #include <sys/fdisk.h>
                     35: #include <sys/filsys.h>
                     36: #include <sys/stat.h>
                     37: #include <sys/types.h>
                     38: #include "build0.h"
                     39: #include "serialno.h"
                     40: 
                     41: /* File names. */
                     42: #define DEVICE_FILE            "/tmp/devices"
                     43: 
                     44: /* Manifest constants. */
                     45: #define        VERSION         "5.0"
                     46: #define        USAGE           "Usage: /etc/build [ -dv ]\n"
                     47: #define        ATDEVS          (NPARTN+NPARTN) /* number of AT disk devices    */
                     48: #define        BSIZE           512             /* sector size                  */
                     49: 
                     50: #define        BAR_BAR         "_bar"          /* 1st copy of serial # */
                     51: #define        BAR_ENTRY       "_entry"        /* 2nd copy of serial # */
                     52: #define        MAXSIZE         500             /* suggested max size (MB)      */
                     53: #define        MINSIZE         10              /* required root size (MB)      */
                     54: #define        NEEDSIZE        10              /* suggested min root size (MB) */
                     55: #define        PIPEDEV         "pipedev"       /* kernel pipe F.S. device */
                     56: #define        ROOTDEV         "rootdev"       /* kernel root F.S. device */
                     57: 
                     58: #define        NAMESIZE        6               /* max device name buffer size  */
                     59: #define        NDEVICES        24              /* number of disk devices       */
                     60: 
                     61: /* (unsigned long) sectors to (double) megabytes. */
                     62: #define        meg(sec)        ((double)sec * BSIZE / 1000000.)
                     63: 
                     64: /* Device table structure. */
                     65: typedef        struct  device  {
                     66:        char            d_xname[NAMESIZE];      /* partition table name */
                     67:        char            d_dname[NAMESIZE];      /* device name          */
                     68:        int             d_major;                /* major number         */
                     69:        int             d_minor;                /* minor number         */
                     70:        int             d_flags;                /* flags                */
                     71:        unsigned long   d_size;                 /* size in blocks       */
                     72: }      DEVICE;
                     73: 
                     74: /* Flag bits. */
                     75: #define        F_COH   0x01                            /* COHERENT partition   */
                     76: #define        F_BOOT  0x02                            /* Active               */
                     77: #define        F_ROOT  0x04                            /* Root                 */
                     78: #define        F_FS    0x08                            /* File system exists   */
                     79: #define        F_MOUNT 0x10                            /* Mounted by /etc/rc   */
                     80: #define        F_PROTO 0x20                            /* Proto created        */
                     81: #define        F_SCAN  0x40                            /* Badscanned           */
                     82: #define        F_ATDEV 0x80                            /* AT device            */
                     83: #define        isflag(i, f)    ((devices[i].d_flags & (f)) != 0)
                     84: #define        notflag(i, f)   ((devices[i].d_flags & (f)) == 0)
                     85: #define        clrflag(i, f)   devices[i].d_flags &= ~(f)
                     86: #define        setflag(i, f)   devices[i].d_flags |= (f)
                     87: 
                     88: /*
                     89:  * Device table.
                     90:  * add_devices() adds entries for devices created by /etc/mkdev.
                     91:  * fdisk() zaps the entries for which the xdevice open fails.
                     92:  */
                     93: DEVICE devices[NDEVICES] = {
                     94:        { "at0x", "at0a", AT_MAJOR, 0, F_ATDEV, 0L },
                     95:        { "at0x", "at0b", AT_MAJOR, 1, F_ATDEV, 0L },
                     96:        { "at0x", "at0c", AT_MAJOR, 2, F_ATDEV, 0L },
                     97:        { "at0x", "at0d", AT_MAJOR, 3, F_ATDEV, 0L },
                     98:        { "at1x", "at1a", AT_MAJOR, 4, F_ATDEV, 0L },
                     99:        { "at1x", "at1b", AT_MAJOR, 5, F_ATDEV, 0L },
                    100:        { "at1x", "at1c", AT_MAJOR, 6, F_ATDEV, 0L },
                    101:        { "at1x", "at1d", AT_MAJOR, 7, F_ATDEV, 0L }
                    102: };
                    103: 
                    104: /* Externals. */
                    105: extern long    atol();
                    106: extern char    *fgets();
                    107: extern long    lseek();
                    108: extern time_t  time();
                    109: 
                    110: /* Forward. */
                    111: void   add_devices();
                    112: void   badscan();
                    113: void   copy();
                    114: char   *devname();
                    115: void   done();
                    116: int    exists_and_nz();
                    117: void   fdisk();
                    118: void   get_timezone();
                    119: int    is_fs();
                    120: void   mkdev();
                    121: void   mkfs();
                    122: void   new_boot();
                    123: void   patches();
                    124: char   *protoname();
                    125: char   *rawname();
                    126: void   rootpatch();
                    127: void   save_files();
                    128: void   set_date();
                    129: void   uucp();
                    130: void   user_devices();
                    131: void   welcome();
                    132: char   *xname();
                    133: 
                    134: /* Globals. */
                    135: int    active = -1;                    /* active partition     */
                    136: char   *activeos;                      /* active partition OS  */
                    137: char   buf2[NBUF];                     /* extra buffer         */
                    138: HDISK_S        hd;                             /* hard disk boot block */
                    139: int    mboot;                          /* mboot replaced       */
                    140: int    ncohdev;                        /* number of COHERENT devices */
                    141: int    ndevices = ATDEVS;              /* number of devices    */
                    142: int    protoflag;                      /* prototypes created   */
                    143: int    root;                           /* root partition       */
                    144: char   tzone[NBUF];                    /* timezone             */
                    145: char   tzone5[NBUF];                   /* timezone for Sys V   */
                    146: int    update;                         /* update, rather than install */
                    147: 
                    148: main(argc, argv) int argc; char *argv[];
                    149: {
                    150:        register char *s;
                    151: 
                    152:        argv0 = argv[0];
                    153:        abortmsg = 1;
                    154:        usagemsg = USAGE;
                    155:        if (argc > 1 && argv[1][0] == '-') {
                    156:                for (s = &argv[1][1]; *s; ++s) {
                    157:                        switch(*s) {
                    158:                        case 'd':       ++dflag;        break;
                    159:                        case 'u':       ++update;       break;
                    160:                        case 'v':       ++vflag;        break;
                    161:                        case 'V':
                    162:                                fprintf(stderr, "%s: V%s\n", argv0, VERSION);
                    163:                                break;
                    164:                        default:        usage();        break;
                    165:                        }
                    166:                }
                    167:                --argc;
                    168:                ++argv;
                    169:        }
                    170:        if (argc != 1)
                    171:                usage();
                    172: 
                    173:        welcome();
                    174:        set_date();
                    175:        mkdev();
                    176: 
                    177:        fdisk();
                    178:        if (update) {
                    179:                new_boot();     /* write out new boot block for tboot */
                    180:                save_files();
                    181:        } else {
                    182:                badscan();
                    183:                mkfs();
                    184:        }
                    185:        copy();
                    186: 
                    187:        if (!update)
                    188:                user_devices();
                    189:        uucp();
                    190:        rootpatch();
                    191:        patches();
                    192:        sys("/bin/echo /etc/build: success >>/mnt/etc/install.log", S_NONFATAL);
                    193:        sprintf(cmd, "TIMEZONE=\"%s\" /bin/date >>/mnt/etc/install.log", tzone);
                    194:        sys(cmd, S_NONFATAL);
                    195:        sys("/bin/echo >>/mnt/etc/install.log", S_NONFATAL);
                    196:        done();
                    197:        sync();
                    198:        sys("/etc/reboot -p", S_IGNORE);
                    199: 
                    200:        /* NOTREACHED */
                    201:        exit(0);
                    202: }
                    203: 
                    204: /*
                    205:  * Append devices as specified by /etc/mkdev to devices table.
                    206:  */
                    207: void
                    208: add_devices()
                    209: {
                    210:        register FILE *fp;
                    211:        register int i, n;
                    212: 
                    213:        if ((fp = fopen(DEVICE_FILE, "r")) == NULL)
                    214:                return;
                    215:        for (i = ndevices; i < NDEVICES; i++) {
                    216:                n = fscanf(fp, "%s %s %d %d\n",
                    217:                        devices[i].d_xname, devices[i].d_dname,
                    218:                        &devices[i].d_major, &devices[i].d_minor);
                    219:                if (n == 0 || n == EOF)
                    220:                        break;
                    221:                else if (n != 4)
                    222:                        fatal("scanf failed on %s, n=%d", DEVICE_FILE, n);
                    223:                ++ndevices;
                    224:        }
                    225:        if (i == NDEVICES)
                    226:                nonfatal("too many devices, excess ignored");
                    227:        fclose(fp);
                    228: }
                    229: 
                    230: /*
                    231:  * Scan each COHERENT device for bad blocks.
                    232:  */
                    233: void
                    234: badscan()
                    235: {
                    236:        register int i;
                    237:        register char *name;
                    238: 
                    239:        cls(1);
                    240:        printf(
                    241: "The next step in installation is to scan each COHERENT partition\n"
                    242: "for bad blocks.  This will not write to the partition being scanned.\n"
                    243: "Be patient.  This takes a few minutes.\n"
                    244:                );
                    245:        for (i = 0; i < ndevices; i++) {
                    246:                if (notflag(i, F_COH) || notflag(i, F_ATDEV))
                    247:                        continue;       /* scan only AT device COH partitions */
                    248:                printf("\n");
                    249:                name = devname(i, 0);
                    250:                if (isflag(i, F_FS)) {
                    251:                        printf(
                    252: "Partition %d (%s) already contains a COHERENT filesystem.\n"
                    253: "If you wish to continue to use the existing filesystem, you can skip\n"
                    254: "scanning it for bad blocks.  If you want to replace it with an empty\n"
                    255: "filesystem, you must scan it for bad blocks first.\n",
                    256:                                i, name);
                    257:                        if (yes_no("Do you want to scan %s for bad blocks",
                    258:                                name) == 0)
                    259:                                continue;
                    260:                }
                    261:                printf("Scanning partition %d:\n", i);
                    262:                setflag(i, F_SCAN);
                    263:                sprintf(cmd, "/etc/badscan -v -o %s %s %s",
                    264:                        protoname(i), rawname(i, 1), xname(i, 1));
                    265:                if (sys(cmd, S_NONFATAL) == 0) {
                    266:                        setflag(i, F_PROTO);
                    267:                        ++protoflag;
                    268:                }
                    269:        }
                    270: }
                    271: 
                    272: /*
                    273:  * Mount the root filesystem, copy files to it, patch /coherent.
                    274:  * Kludge around as required.
                    275:  */
                    276: void
                    277: copy()
                    278: {
                    279:        cls(0);
                    280:        printf(
                    281: "The next step is to copy some COHERENT files from the diskette to the\n"
                    282: "root filesystem of your hard disk.  This will take a few minutes...\n"
                    283:                );
                    284: 
                    285:        /* Mount the filesystem. */
                    286:        sprintf(cmd, "/etc/mount %s /mnt", devname(root, 1));
                    287: 
                    288:        sys(cmd, S_FATAL);
                    289: 
                    290:        if(update){
                    291:                printf(
                    292: "The existing /coherent kernel on the root file system will now be renamed to\n"
                    293: "coh.B4.420. After this the remainder of diskette #1 will be copied.\n\n"
                    294:                );
                    295: 
                    296:                /* move the existing kernel names /coherent to coh.B4.420 */
                    297:                sprintf(cmd,"/bin/cp /mnt/coherent /mnt/coh.B4.420 2>/dev/null");
                    298:                sys(cmd,S_NONFATAL);
                    299:        }
                    300: 
                    301:        /* Copy the boot floppy. */
                    302:        sprintf(cmd, "/bin/cpdir -ad%s -smnt -sbegin -stmp %s / /mnt",
                    303:          (vflag) ? "v" : "", (update) ? "`cat /conf/upd_suppress`" : "");
                    304:        sys(cmd, S_FATAL);
                    305: 
                    306:        /* Copy idtune and idenable data files. */
                    307:        sprintf(cmd, "/bin/cp %s %s /mnt/conf", IDCMDFILE, IDVARFILE);
                    308:        sys(cmd, S_FATAL);
                    309: 
                    310:        /* Copy patch file for debugging. */
                    311:        sprintf(cmd, "/bin/cp %s /mnt/conf", PATCHFILE);
                    312:        sys(cmd, S_FATAL);
                    313: 
                    314:        if (!is_dir("/mnt/mnt"))
                    315:                sys("/bin/mkdir /mnt/mnt", S_FATAL);
                    316:        sys("/bin/chmog 0755 bin bin /mnt/mnt", S_NONFATAL);
                    317: 
                    318:        /* Write entry to /etc/install.log. */
                    319:        sprintf(cmd, "/bin/echo /etc/build: %s %s >>/mnt/etc/install.log",
                    320:                "386",
                    321:                (update) ? "update" : "install");
                    322:        sys(cmd, S_NONFATAL);
                    323:        sprintf(cmd, "TIMEZONE=\"%s\" /bin/date >>/mnt/etc/install.log", tzone);
                    324:        sys(cmd, S_NONFATAL);
                    325: 
                    326:        /* If /etc/mkdev created devices in /tmp/dev, copy them to /dev. */
                    327:        /* Remove the copies in /tmp/dev on the hard disk. */
                    328:        if (exists("/tmp/dev"))
                    329:                sys("/bin/cpdir -d /tmp/dev /mnt/dev", S_FATAL);
                    330:        if (exists("/tmp/drvld.all")) {
                    331:                sys("/bin/cp /tmp/drvld.all /mnt/etc/drvld.all", S_NONFATAL);
                    332:                sys("/bin/chmog 0744 root root /mnt/etc/drvld.all", S_NONFATAL);
                    333:        }
                    334: 
                    335:        sys("/bin/cat /tmp/ttys >>/mnt/etc/ttys", S_NONFATAL);
                    336:        sys("/bin/cp /tmp/id-cmd /mnt/etc/conf/bin/id-cmd", S_NONFATAL);
                    337:        sys("/bin/chmog 544 root root /mnt/etc/conf/bin/id-cmd", S_NONFATAL);
                    338: 
                    339:        /* Grow /lost+found to make room for files. */
                    340:        sys("cd /mnt/lost+found \n"
                    341:            "/bin/touch `/bin/from 1 to 200` \n"
                    342:            "/bin/rm *", S_IGNORE);
                    343: 
                    344:        /* Create /autoboot. */
                    345:        sys("/bin/ln -f /mnt/coherent /mnt/autoboot", S_FATAL);
                    346: 
                    347:        /* Replace the build version of /etc/brc with the install version. */
                    348:        sys("/bin/rm /mnt/etc/brc", S_NONFATAL);
                    349:        if (update)
                    350:                sys("/bin/ln -f /mnt/etc/brc.update /mnt/etc/brc", S_FATAL);
                    351:        else
                    352:                sys("/bin/ln -f /mnt/etc/brc.install /mnt/etc/brc", S_FATAL);
                    353: 
                    354:        /* Link root device to /dev/root. */
                    355:        sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/root", devname(root, 0));
                    356:        sys(cmd, S_FATAL);
                    357: 
                    358:        /* Write the timezone to /etc/timezone. */
                    359:        sprintf(cmd, "/bin/echo export TIMEZONE=\\\"%s\\\" >/mnt/etc/timezone", tzone);
                    360:        sys(cmd, S_NONFATAL);
                    361:        sprintf(cmd, "/bin/echo export TZ=\\\"%s\\\" >>/mnt/etc/timezone", tzone5);
                    362:        sys(cmd, S_NONFATAL);
                    363: 
                    364:        if (!update) {
                    365:                /* Write the serial number to /etc/serialno. */
                    366:                sprintf(cmd, "/bin/echo %s >/mnt/etc/serialno", serialno);
                    367:                sys(cmd, S_NONFATAL);
                    368:        }
                    369: 
                    370:        /* Save the prototypes from /tmp to /conf. */
                    371:        if (protoflag)
                    372:                sys("/bin/mv /tmp/*.proto /mnt/conf", S_NONFATAL);
                    373: }
                    374: 
                    375: /*
                    376:  * Generate a device name from a DEVICE entry name.
                    377:  * Return a pointer to the statically allocated name.
                    378:  * If flag and not one of the built-in AT device names,
                    379:  * the device is in /tmp/dev rather than /dev.
                    380:  * Sleazy hack: this always writes "/tmp/dev/..." in the buffer and
                    381:  * massages the return value accordingly so that subsequent calls
                    382:  * with same i but different flag will not clobber previous return values.
                    383:  */
                    384: char *
                    385: devname(i, flag) int i, flag;
                    386: {
                    387:        static char name[4+4+1+NAMESIZE];       /* e.g. "/tmp/dev/at0a" */
                    388: 
                    389:        sprintf(name, "/tmp/dev/%s", devices[i].d_dname);
                    390:        return (flag && notflag(i, F_ATDEV)) ? name : name+4;
                    391: }
                    392: 
                    393: /*
                    394:  * Done.
                    395:  * Print useful information.
                    396:  */
                    397: void
                    398: done()
                    399: {
                    400:        cls(1);
                    401:        printf(
                    402: "You have installed the COHERENT operating system onto your hard disk.\n"
                    403: "To install files from the remaining diskettes in the installation kit,\n"
                    404: "you must boot the COHERENT system from the hard disk.  It will prompt\n"
                    405: "you to install the remaining diskettes in the installation kit.\n"
                    406: "\n"
                    407: "After you finish reading this information, remove the floppy disk,\n"
                    408: "hit <Enter> and your system will automatically reboot.\n"
                    409: "\n"
                    410:                );
                    411:        if (mboot) {
                    412:                printf(
                    413: "If you type a partition number (0 to 7) while\n"
                    414: "the boot procedure is trying to read the floppy disk,\n"
                    415: "your system will boot the operating system on that partition.\n"
                    416:                );
                    417:                if (active != -1) {
                    418:                        printf("If you type nothing, your system will boot ");
                    419:                        if (active == root)
                    420:                                printf("COHERENT (partition %d).\n", active);
                    421:                        else {
                    422:                                printf("active partition %d", active);
                    423:                                if (activeos != NULL)
                    424:                                        printf(" (%s)", activeos);
                    425:                                printf(".\n", active);
                    426:                        }
                    427:                }
                    428:        } else {
                    429:                printf(
                    430: "You must boot the new COHERENT root filesystem on partition %d.\n",
                    431:                  root);
                    432:        }
                    433: 
                    434:        printf(
                    435: "\nNow remove the floppy disk so your system does not boot from the floppy.\n");
                    436: 
                    437:        if (mboot && root != active)
                    438:                printf(
                    439: "You MUST type %d when the system tries to read the floppy disk during the boot\n"
                    440: "procedure to boot the partition containing the new COHERENT root filesystem.\n",
                    441:                        root);
                    442: }
                    443: 
                    444: /*
                    445:  * See if the specified file exists and has non-zero length.
                    446:  */
                    447: exists_and_nz(fn)
                    448: char *fn;
                    449: {
                    450:        struct stat s;
                    451: 
                    452:        if (stat(fn, &s) == -1)
                    453:                return 0;                       /* does not exist */
                    454:        return (s.st_size > 0);                 /* exists and length > 0 */
                    455: }
                    456: 
                    457: /*
                    458:  * Get partition table information.
                    459:  */
                    460: void
                    461: fdisk()
                    462: {
                    463:        register int fd, i, j, n, part, cohpart, flag;
                    464:        char *fname, *s;
                    465: 
                    466:        cls(1);
                    467:        if (update) {
                    468:                printf("Reading existing partition tables...\n");
                    469:        } else {
                    470:                printf(
                    471: "This installation procedure allows you to create one or more partitions\n"
                    472: "on your hard disk to contain the COHERENT system and its files.\n"
                    473: "Each disk drive may contain no more than four logical partitions.\n"
                    474: "If all four partitions on your disk are already in use, you will\n"
                    475: "have to overwrite at least one of them to install COHERENT.\n"
                    476: "If your disk uses fewer than four partitions and has enough unused space\n"
                    477: "for COHERENT (%d megabytes), you can install COHERENT into the unused space.\n"
                    478: "If you intend to install MS-DOS after installing COHERENT,\n"
                    479: "you must leave the first physical partition free for MS-DOS.\n"
                    480: "\n"
                    481: "The next part of the installation procedure will let you change the\n"
                    482: "partitions on your hard disk.  Data on unchanged hard disk partitions\n"
                    483: "will not be changed.  However, data already on your hard disk may be\n"
                    484: "destroyed if you change the base or the size of a logical partition,\n"
                    485: "or if you change the order of the partition table entries.\n"
                    486: "If you need to back up existing data from the hard disk,\n"
                    487: "type <Ctrl-C> now to interrupt COHERENT installation; then reboot your\n"
                    488: "system and back up your hard disk data onto diskettes.\n"
                    489: "\n", NEEDSIZE);
                    490:                cls(1);
                    491:                printf(
                    492: "COHERENT initialization normally writes a new master bootstrap program onto\n"
                    493: "your hard disk.  The COHERENT master boot allows you to boot the operating\n"
                    494: "system on one selected disk partition (the active partition) automatically;\n"
                    495: "it also allows you to boot the operating system on any disk partition by\n"
                    496: "typing a key when you reboot.  Mark Williams strongly recommends that you\n"
                    497: "use the COHERENT master boot.  However, the COHERENT master boot may not\n"
                    498: "work with some operating systems (for example, Xenix) if you make the\n"
                    499: "COHERENT partition active; instead, leave the other partition (e.g. Xenix)\n"
                    500: "active and boot COHERENT by typing a key.  If you do not use the COHERENT\n"
                    501: "bootstrap, you must understand how to boot the COHERENT partition using your\n"
                    502: "existing bootstrap program.\n"
                    503: "\n"
                    504:                );
                    505:                if (yes_no("Do you want to use the COHERENT master boot"))
                    506:                        ++mboot;
                    507: 
                    508: retry:
                    509:        /* Construct an /etc/fdisk command with appropriate xdevice names. */
                    510:                strcpy(cmd, "/etc/fdisk -cB");
                    511:                if (mboot)
                    512:                        strcat(cmd, "b /conf/mboot");
                    513:                for (i = 0; i < ndevices; i++) {
                    514:                        if (i == 0
                    515:                         || strcmp(devices[i-1].d_xname, devices[i].d_xname) != 0) {
                    516:                                if ((fd = open(xname(i, 1), 0)) < 0)
                    517:                                        continue;
                    518:                                close(fd);
                    519:                                strcat(cmd, " ");
                    520:                                strcat(cmd, xname(i, 1));
                    521:                        }
                    522:                }
                    523:                sys(cmd, S_FATAL);              /* do the fdisk command */
                    524:        } /* !update */
                    525: 
                    526:        /* Read the partition table and set device flags appropriately. */
                    527:        for (i = part = 0; i < ndevices; ++i) {
                    528:                if (i != 0
                    529:                 && strcmp(devices[i-1].d_xname, devices[i].d_xname) == 0)
                    530:                        continue;               /* partition already done */
                    531:                fname = xname(i, 1);
                    532:                if ((fd = open(fname, 0)) < 0)
                    533:                        continue;               /* cannot open xdevice */
                    534:                if (read(fd, &hd, sizeof hd) != sizeof hd)
                    535:                        fatal("%s: read failed", fname);
                    536:                close(fd);
                    537:                if (hd.hd_sig != HDSIG) {
                    538:                        nonfatal("%s: invalid partition table", fname);
                    539:                        continue;
                    540:                }
                    541:                /* The partition table is valid, check its partitions. */
                    542:                for (j = 0; j < NPARTN && i + j < ndevices; j++) {
                    543:                        n = i + j;              /* index in devices[] */
                    544:                        if (part != n) {
                    545:                                /*
                    546:                                 * Copy over unopenable partitions.
                    547:                                 * This allows subsequent code to use
                    548:                                 * the devices[] index as the partition number.
                    549:                                 */
                    550:                                devices[part] = devices[n];
                    551:                                n = part;
                    552:                        }
                    553:                        part++;                 /* another valid partition */
                    554:                        if (hd.hd_partn[j].p_boot != 0) {
                    555:                                setflag(n, F_BOOT);
                    556:                                if (active == -1)
                    557:                                        active = n;     /* first active partition */
                    558:                                switch(hd.hd_partn[j].p_sys) {
                    559:                                case SYS_COH:
                    560:                                        activeos = "COHERENT";
                    561:                                        break;
                    562:                                case SYS_DOS_12:
                    563:                                case SYS_DOS_16:
                    564:                                case SYS_DOS_XP:
                    565:                                case SYS_DOS_LARGE:
                    566:                                        activeos = "MS-DOS";
                    567:                                        break;
                    568:                                case SYS_XENIX:
                    569:                                        activeos = "Xenix";
                    570:                                        break;
                    571:                                default:
                    572:                                        activeos = NULL;
                    573:                                        break;
                    574:                                }
                    575:                        }
                    576:                        if (hd.hd_partn[j].p_sys != SYS_COH)
                    577:                                continue;
                    578: 
                    579:                        /* Make sure the device can be accessed. */
                    580:                        s = devname(n, 1);
                    581:                        if (!exists(s)) {
                    582:                                nonfatal("cannot open COHERENT partition %d (%s)",
                    583:                                        n, devname(n, 0));
                    584:                                continue;
                    585:                        } else if (hd.hd_partn[j].p_size == 0L) {
                    586:                                nonfatal("COHERENT partition %d (%s) is empty",
                    587:                                        j, devname(n, 0));
                    588:                                continue;
                    589:                        }
                    590: 
                    591:                        /* OK, set flags in the device table. */
                    592:                        ++ncohdev;
                    593:                        setflag(n, F_COH);
                    594:                        devices[n].d_size = hd.hd_partn[j].p_size;
                    595:                        if (is_fs(s, devices[n].d_size))
                    596:                                setflag(n, F_FS);
                    597: 
                    598:                        /* Make sure the device is not mounted. */
                    599:                        sprintf(cmd, "/etc/umount %s 2>/dev/null", s);
                    600:                        sys(cmd, S_IGNORE);
                    601:                }
                    602:        }
                    603:        ndevices = part;
                    604:        if (ndevices == 0)
                    605:                fatal("cannot open partition tables");
                    606:        else if (ncohdev == 0)
                    607:                fatal("no COHERENT partition found");
                    608:        cls(0);
                    609:        printf("Your system includes %d COHERENT partition%s:\n",
                    610:                ncohdev, (ncohdev == 1) ? "" : "s");
                    611:        printf("Drive Partition\t  Device\tMegabytes\n");
                    612:        for (flag = i = 0; i < ndevices; i++)
                    613:                if (isflag(i, F_COH)) {
                    614:                        cohpart = i;
                    615:                        printf("%3d\t%3d\t%s\t%.2f\n",
                    616:                                i/NPARTN,
                    617:                                i,
                    618:                                devname(i, 0),
                    619:                                meg(devices[i].d_size));
                    620:                        if (((int)meg(devices[i].d_size)) > MAXSIZE)
                    621:                                flag = 1;
                    622:                }
                    623:        if (!update && flag) {
                    624:                printf(
                    625: "\n"
                    626: "Your system includes a large COHERENT filesystem (larger than %d megabytes).\n"
                    627: "You should repartition the hard disk to define smaller COHERENT partitions.\n",
                    628:                        MAXSIZE);
                    629:                if (yes_no("Do you want to repartition the hard disk"))
                    630:                        goto retry;
                    631:                printf("\n");
                    632:        }
                    633: 
                    634:        if (ncohdev == 1) {
                    635:                root = cohpart;
                    636:                setflag(root, F_ROOT);
                    637:                return;
                    638:        }
                    639:        printf(
                    640: "You must specify one COHERENT partition as the root filesystem.\n"
                    641:                );
                    642:        if (!update)
                    643:                printf(
                    644: "The root filesystem contains the files normally used by COHERENT.\n"
                    645: "The root filesystem should contain at least %d megabytes.\n",
                    646:                        NEEDSIZE);
                    647:        if (ndevices > ATDEVS)
                    648:                printf(
                    649: "The COHERENT root filesystem must be on partition 0 through 7.\n"
                    650:                        );
                    651:        if (active != -1 && isflag(active, F_COH)) {
                    652:                printf("COHERENT partition %d is marked as active in the partition table.\n",
                    653:                        active);
                    654:                if (!update)
                    655:                        printf(
                    656: "If you choose it as the root, you can boot COHERENT automatically.\n"
                    657:                                );
                    658:        }
                    659:        printf("\n");
                    660: again:
                    661:        if (update)
                    662:                s = get_line("Which partition contains the COHERENT root filesystem?");
                    663:        else
                    664:                s = get_line("Which partition do you want to be the root filesystem?");
                    665:        root = *s - '0';
                    666:        if (*++s != '\0' || root < 0 || root >= ATDEVS || notflag(root, F_COH)) {
                    667:                printf("Enter a number between 0 and 7 which specifies a COHERENT partition.\n");
                    668:                goto again;
                    669:        }
                    670: 
                    671:        if (meg(devices[root].d_size) < (double)NEEDSIZE) {
                    672:                if (update) {
                    673:                        printf(
                    674: "\n"
                    675: "Your current COHERENT 4.0.x root filesystem is too small to contain the\n"
                    676: "COHERENT 4.2.0 update along with the on-line manual pages and the on-line\n"
                    677: "dictionary.  If you wish to have the COHERENT 4.2.0 on-line manual pages and\n"
                    678: "the on-line dictionary installed, you will need to do the following:\n\n"
                    679: "\t1) Exit from the update.\n"
                    680: "\t2) Boot from your existing COHERENT root partition.\n"
                    681: "\t3) Perform a full \"backup\" of ALL PARTITIONS on your hard disk\n"
                    682: "\t   include all of your existing programs, files, and any system\n"
                    683: "\t   files that you have modified using backup utilities \"cpio\",\n"
                    684: "\t   \"ustar\", or \"tar\".  If your hard disk includes partitions\n"
                    685: "\t   assigned to other operating systems, be sure to back these up also!\n"
                    686: "\t4) Perform a full installation of COHERENT 386 using the same disks\n"
                    687: "\t   supplied for the update.  Note that you will need to increase the\n"
                    688: "\t   size of the root partition, or you will need to select a different\n"
                    689: "\t   partition to contain the root filesystem.   Please refer to the\n"
                    690: "\t   chapter on installation found in the COHERENT 386 release notes.\n"
                    691:                                );
                    692:                        sync();
                    693:                        if (yes_no("Do you wish to abort the update"))
                    694:                                fatal("Insufficient disk space for update!");
                    695:                } else {
                    696:                        printf("Partition %d contains only %.2f megabytes.\n",
                    697:                                root, meg(devices[root].d_size));
                    698:                        if (meg(devices[root].d_size) < (double)MINSIZE) {
                    699:                                printf("It is too small to contain the COHERENT root filesystem.\n");
                    700:                                goto again;
                    701:                        }
                    702:                        if (!yes_no("Are you sure you want it to be the root partition"))
                    703:                                goto again;
                    704:                }
                    705:        }
                    706:        setflag(root, F_ROOT);
                    707: }
                    708: 
                    709: /*
                    710:  * Set up a nonstandard timezone.
                    711:  */
                    712: void
                    713: get_timezone(dstflag)
                    714: int dstflag;
                    715: {
                    716:        register char *s;
                    717:        int diff;
                    718:        char std_abbr[20], dst_abbr[20];
                    719:        int east_of_gr;
                    720: 
                    721:        /* tzone5 is like tzone except no colons and number is in hours */
                    722: 
                    723:        printf(
                    724: "You need to specify an abbreviation for your timezone,\n"
                    725: "whether you are east or west of Greenwich, England,\n"
                    726: "and the difference in minutes between your timezone\n"
                    727: "and Greenwich Time (called UT or GMT).  For example,\n"
                    728: "Germany is 60 minutes of time east of Greenwich.\n"
                    729:                );
                    730:        s = get_line("Abbreviation for your timezone:");
                    731:        strcpy(std_abbr, s);
                    732:        east_of_gr = yes_no("Is your timezone east of Greenwich");
                    733:        s = get_line("Difference in minutes from GMT:");
                    734:        diff = atoi(s);
                    735:        if (east_of_gr)
                    736:                diff = -diff;
                    737:        if (dstflag) {
                    738:                s = get_line("Abbreviation for your daylight savings timezone:");
                    739:                strcpy(dst_abbr, s);
                    740:                sprintf(tzone, "%s:%d:%s:1.1.4", std_abbr, diff, dst_abbr);
                    741:                sprintf(tzone5, "%s%d%s", std_abbr, diff/60, dst_abbr);
                    742:        } else {
                    743:                sprintf(tzone, "%s:%d:", std_abbr, diff);
                    744:                sprintf(tzone5, "%s%d", std_abbr, diff/60);
                    745:        }
                    746: }
                    747: 
                    748: /*
                    749:  * Check if a special file is a well-formed filesystem.
                    750:  * This routine is derived from code in "mount.c".
                    751:  * Here the check that "special" is a block special file is eliminated
                    752:  * and the size is checked against the partition size.
                    753:  */
                    754: int
                    755: is_fs(special, size) char *special; unsigned long size;
                    756: {
                    757:        static struct filsys f;
                    758:        register int fd;
                    759:        register struct filsys *fp;
                    760:        register daddr_t *dp;
                    761:        register ino_t *ip, maxinode;
                    762: 
                    763:        if ((fd = open(special, 0)) < 0                 /* cannot open */
                    764:         || lseek(fd, (long)SUPERI*BSIZE, 0) == -1L     /* seek failed */
                    765:         || read(fd, &f, sizeof(f)) != sizeof(f))       /* read failed */
                    766:                return 0;
                    767:        close(fd);
                    768: 
                    769:        /* Canonical stuff. */
                    770:        fp = &f;
                    771:        canshort(fp->s_isize);
                    772:        candaddr(fp->s_fsize);
                    773:        canshort(fp->s_nfree);
                    774:        for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
                    775:                candaddr(*dp);
                    776:        canshort(fp->s_ninode);
                    777:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
                    778:                canino(*ip);
                    779:        candaddr(fp->s_tfree);
                    780:        canino(fp->s_tinode);
                    781: 
                    782:        /* Test for rationality. */
                    783:        maxinode = (fp->s_isize - INODEI) * INOPB + 1;
                    784:        if (fp->s_isize >= fp->s_fsize)
                    785:                return 0;
                    786:        if ((fp->s_tfree < fp->s_nfree)
                    787:        ||  (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
                    788:                return 0;
                    789:        if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
                    790:                return 0;
                    791:        for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
                    792:                if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
                    793:                        return 0;
                    794:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
                    795:                if ((*ip < 1) || (*ip > maxinode))
                    796:                        return 0;
                    797:        if (fp->s_fsize > (daddr_t)size)
                    798:                return 0;
                    799:        if (fp->s_fsize > (daddr_t)size)
                    800:                nonfatal("warning: filesystem size=%ld but partition size=%ld",
                    801:                        (long)fp->s_fsize, size);
                    802:        return 1;
                    803: }
                    804: 
                    805: /*
                    806:  * Make new devices with /etc/mkdev if appropriate.
                    807:  */
                    808: void
                    809: mkdev()
                    810: {
                    811:        int hdc;
                    812: 
                    813:        cls(0);
                    814: printf("Most PC compatible computer systems use MFM, RLL, IDE, or ESDI disk\n");
                    815: printf("controllers and disk drives.  A few percent use SCSI disk drives.\n");
                    816: printf("Please indicate the type(s) of disk drive(s) used in your computer system.\n");
                    817: printf("If you are uncertain of the type, please select choice 1.\n\n");
                    818: printf("Are you using:\n\n");
                    819: printf("1.  AT-compatible hard drive controller (IDE/RLL/MFM/ESDI).\n");
                    820: printf("2.  SCSI hard drive controller.\n");
                    821: printf("3.  Both.\n\n");
                    822:        hdc = get_int(1, 3, "Enter your choice:");
                    823: 
                    824:        /*
                    825:         * Note: -b option to mkdev also OK for update
                    826:         */
                    827:        sprintf(cmd, "/etc/mkdev -b%s%s %s %s",
                    828:                (dflag) ? "d" : "",
                    829:                (vflag) ? "v" : "",
                    830:                (hdc == 1 || hdc == 3) ? "at" : "",
                    831:                (hdc == 2 || hdc == 3) ? "scsi" : "");
                    832:                sys(cmd, S_NONFATAL);
                    833:        if (hdc == 2 || hdc == 3)
                    834:                add_devices();
                    835: }
                    836: 
                    837: /*
                    838:  * Make filesystems on COHERENT partitions.
                    839:  */
                    840: void
                    841: mkfs()
                    842: {
                    843:        register int i;
                    844:        char *name;
                    845: 
                    846:        cls(0);
                    847:        printf(
                    848: "You must create an empty COHERENT filesystem on each COHERENT partition\n"
                    849: "before you can use it.  Creating an empty filesystem will destroy all\n"
                    850: "previously existing data on the partition.\n"
                    851:                );
                    852:        for (i = 0; i < ndevices; i++) {
                    853:                if (notflag(i, F_COH) || (isflag(i, F_ATDEV) && notflag(i, F_SCAN)))
                    854:                        continue;
                    855:                printf("\n");
                    856:                if (isflag(i, F_FS))
                    857:                        printf("Partition %d (%s) already contains a COHERENT filesystem.\n",
                    858:                                i, devname(i, 0));
                    859:                if (i == root)
                    860:                        printf(
                    861: "\nWARNING!!!\n\n"
                    862: "The installation process expects a NEW file system in the root partition.\n"
                    863: "If you are trying to update an existing COHERENT partition, you must run\n"
                    864: "the COHERENT update.  If you are trying to install again after a partial\n"
                    865: "or failed installation, a new root file system must be created again now.\n\n"
                    866:                        );
                    867:                name = devname(i, 1);
                    868: again:
                    869:                if (yes_no("Do you want to create a new COHERENT filesystem on partition %d", i)) {
                    870:                        if (notflag(i, F_ATDEV))
                    871:                                sprintf(cmd, "/etc/mkfs %s %lu", name, devices[i].d_size);
                    872:                        else if (notflag(i, F_PROTO)) {
                    873:                                printf("The attempt to scan %s for bad blocks previously failed.",
                    874:                                        name);
                    875:                                if (yes_no("Do you want to create a new filesystem on it without a bad block list"))
                    876:                                        sprintf(cmd, "/etc/mkfs %s %lu", name, devices[i].d_size);
                    877:                                else
                    878:                                        continue;
                    879:                        } else
                    880:                                sprintf(cmd, "/etc/mkfs %s %s",
                    881:                                        name, protoname(i));
                    882:                        clrflag(i, F_FS);
                    883:                        if (sys(cmd, S_NONFATAL) == 0) {
                    884:                                setflag(i, F_FS);
                    885:                                if (notflag(i, F_PROTO)) {
                    886:                                        /* Stick a boot block on device. */
                    887:                                        /* The proto does it in the other case. */
                    888:                                        sprintf(cmd, "/bin/cp /conf/boot %s", name);
                    889:                                        sys(cmd, S_NONFATAL);
                    890:                                }
                    891: 
                    892:                                /*
                    893:                                 * Mount the file system,
                    894:                                 * create /lost+found,
                    895:                                 * unmount it.
                    896:                                 */
                    897:                                sprintf(cmd, "/etc/mount %s /mnt", name);
                    898:                                if (sys(cmd, S_NONFATAL))
                    899:                                        continue;
                    900:                                sprintf(cmd, "/bin/mkdir /mnt/lost+found");
                    901:                                if (sys(cmd, S_NONFATAL) == 0)
                    902:                                        sys(
                    903: "cd /mnt/lost+found \n"
                    904: "/bin/touch `/bin/from 1 to 200` \n"
                    905: "/bin/rm *",
                    906:                                                S_IGNORE);
                    907:                                sprintf(cmd, "/etc/umount %s", name);
                    908:                                sys(cmd, S_NONFATAL);
                    909:                        } else if (i == root)
                    910:                                fatal("%s: root partition mkfs failed", name);
                    911:                } else if (i == root) {
                    912:                        if (notflag(i, F_FS)) {
                    913:                                printf("You must create a filesystem on the root partition.\n");
                    914:                                goto again;
                    915:                        } else {
                    916:                                /* Stick a boot block on the root device. */
                    917:                                sprintf(cmd, "/bin/cp /conf/boot %s", name);
                    918:                                sys(cmd, S_NONFATAL);
                    919:                        }
                    920:                }
                    921:        }
                    922: }
                    923: 
                    924: /*
                    925:  * Place a bootstrap on the root filesystem.
                    926:  * This is only called from update.
                    927:  */
                    928: void
                    929: new_boot()
                    930: {
                    931:        sprintf(cmd, "/bin/cp /conf/boot %s", devname(root, 1));
                    932:        sys(cmd, S_FATAL);
                    933: }
                    934: 
                    935: /*
                    936:  * Validate "name" to see if its an OK UUCP sitename or domain name.  If
                    937:  * anything suspicious is found, query the user and allow them to change
                    938:  * their answer.  The domain defaults to UUCP.  In order to avoid having
                    939:  * 10,000 machines called bbsuser, no default exists for the sitename.
                    940:  *
                    941:  * Return true if OK, false otherwise.
                    942:  */
                    943: int
                    944: ok_name(name, type)
                    945: unsigned char *name;           /* User's response to site/domain question */
                    946: int    type;                   /* 'd' == domain, 'u' == uucpname/site */
                    947: {
                    948:        int warn = 0;
                    949:        char    save[NBUF];     /* save off name for caller */
                    950: 
                    951:        if (type == 'd' && name[0] == '.')
                    952:                strcpy(name, name+1);
                    953:        strcpy(save, name);
                    954:        if (name[0] == '\0') {                  /* no input ? */
                    955:                if (type == 'd') {
                    956:                        strcpy(name, "UUCP");   /* default to UUCP domain */
                    957:                        return 1;
                    958:                } else {
                    959:                        return 0;               /* no defaults for sitename */
                    960:                }
                    961:        }
                    962:        if (type == 'u' && strlen(name) > 7) {
                    963:                ++warn;
                    964:                printf(
                    965: "The system name you chose is greater than seven characters in length.\n"
                    966:                );
                    967:        }
                    968:        if ((type == 'd' && strspn(name, "abcdefghijklmnopqrstuvwxyz"
                    969:                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    970:                         "0123456789"
                    971:                         ".-_") != strlen(name))
                    972:          || (type == 'u' && strspn(name, "abcdefghijklmnopqrstuvwxyz"
                    973:                         "0123456789") != strlen(name))) {
                    974:                ++warn;
                    975:                printf("The name you chose contains invalid characters.\n");
                    976:        }
                    977:        if (!warn)
                    978:                return 1;
                    979:        if (yes_no("Would you like to choose a different name"))
                    980:                return 0;
                    981:        strcpy(name, save);
                    982:        return 1;
                    983: }
                    984: 
                    985: /*
                    986:  * If PATCHFILE exists, execute it.
                    987:  */
                    988: void
                    989: patches()
                    990: {
                    991:        printf(
                    992: "\nThe kernel on your hard drive will now be patched to run on your system.\n");
                    993:        if (access(PATCHFILE, F_OK) == 0) {
                    994:                sprintf(cmd, "/bin/sh %s", PATCHFILE);
                    995:                sys(cmd, S_NONFATAL);
                    996:        }
                    997: }
                    998: 
                    999: /*
                   1000:  * Generate a prototype name from a DEVICE entry name.
                   1001:  * Return a pointer to the statically allocated name.
                   1002:  */
                   1003: char *
                   1004: protoname(i) int i;
                   1005: {
                   1006:        static char pname[5+NAMESIZE+6];        /* e.g. "/tmp/at0a.proto" */
                   1007: 
                   1008:        sprintf(pname, "/tmp/%s.proto", devices[i].d_dname);
                   1009:        return pname;
                   1010: }
                   1011: 
                   1012: /*
                   1013:  * Generate a raw device name from a DEVICE entry name.
                   1014:  * Return a pointer to the statically allocated name.
                   1015:  * If flag and not one of the built-in AT device names,
                   1016:  * the device is in /tmp/dev rather than /dev.
                   1017:  */
                   1018: char *
                   1019: rawname(i, flag) int i, flag;
                   1020: {
                   1021:        static char rname[4+4+1+1+NAMESIZE];    /* e.g. "/tmp/dev/rat0a" */
                   1022: 
                   1023:        sprintf(rname, "/tmp/dev/r%s", devices[i].d_dname);
                   1024:        return (flag && notflag(i,  F_ATDEV)) ? rname : rname+4;
                   1025: }
                   1026: 
                   1027: /*
                   1028:  * Patches to be done to the kernel - but can't do them yet because
                   1029:  * kernel hasn't been linked.
                   1030:  */
                   1031: void
                   1032: rootpatch()
                   1033: {
                   1034:        char line[120];
                   1035: 
                   1036:        /*
                   1037:         * After fdisk() we know "root".  Write to PATCHFILE the patches
                   1038:         * that will be needed when a new kernel is linked at /mnt/coherent.
                   1039:         */
                   1040:        /* For third kernel. */
                   1041:        sprintf(line, "unsigned long\t%s = 0x%lx;", BAR_BAR, atol(serialno));
                   1042:        cohtune_ent("cohmain", BAR_BAR, line);
                   1043: 
                   1044:        sprintf(line, "unsigned long\t%s = 0x%lx;", BAR_ENTRY, atol(serialno));
                   1045:        cohtune_ent("cohmain", BAR_ENTRY, line);
                   1046: 
                   1047:        sprintf(line, "dev_t\t\t%s = makedev(%d,%d);",
                   1048:          ROOTDEV, devices[root].d_major, devices[root].d_minor);
                   1049:        cohtune_ent("cohmain", ROOTDEV, line);
                   1050: 
                   1051:        sprintf(line, "dev_t\t\t%s = makedev(%d,%d);",
                   1052:          PIPEDEV, devices[root].d_major, devices[root].d_minor);
                   1053:        cohtune_ent("cohmain", PIPEDEV, line);
                   1054: 
                   1055:        /* For the second kernel. */
                   1056:        sprintf(cmd,
                   1057:          "echo /conf/patch -v /mnt/coherent ronflag=0 "
                   1058:          "\\\"%s\\=makedev\\(%d,%d\\)\\\" "
                   1059:          "\\\"%s\\=makedev\\(%d,%d\\)\\\" >> %s\n",
                   1060:          ROOTDEV, devices[root].d_major, devices[root].d_minor,
                   1061:          PIPEDEV, devices[root].d_major, devices[root].d_minor, PATCHFILE);
                   1062:        sys(cmd, S_FATAL);
                   1063: }
                   1064: 
                   1065: /*
                   1066:  * Need to mount root.
                   1067:  * Need to set serialno.
                   1068:  * Remove /usr/man/{ALL,COHERENT,MULTI}, /usr/man/man.tar*
                   1069:  * Save off any special files before copying in the update
                   1070:  * Need to umount root.
                   1071:  */
                   1072: void
                   1073: save_files()
                   1074: {
                   1075:        char    buf[20];                /* more than enough for a serial # */
                   1076:        int     fd;                     /* file descriptor */
                   1077:        int     i;
                   1078:        char    *s;
                   1079: 
                   1080:        cls(1);
                   1081:        printf("We will now mount your existing COHERENT root filesystem...\n");
                   1082:        sprintf(cmd, "/etc/mount %s /mnt", devname(root, 1));
                   1083:        sys(cmd, S_FATAL);
                   1084: 
                   1085:        if (!is_dir("/mnt/dev"))        /* sanity check! */
                   1086:                fatal("Corrupt or incorrect root filesystem specified");
                   1087:        /*
                   1088:         * Read in the old 286 serial number and save it off for later.
                   1089:         * If it doesn't exist on the disk, make the user re-enter
                   1090:         * the old serial number by hand.
                   1091:         */
                   1092:        serialno[0] = '\0';
                   1093:        buf[0] = '\0';
                   1094:        if ((fd = open("/mnt/etc/serialno", 0)) >= 0) {
                   1095:                read(fd, buf, sizeof(buf)-1);   /* ignore errors */
                   1096:                close(fd);
                   1097:                if (!isserial(buf))             /* sets serialno[] */
                   1098:                        serialno[0] = '\0';
                   1099:        }
                   1100:        if (serialno[0] == '\0') {
                   1101:                printf(
                   1102: "\nA card included with your original COHERENT distribution gives the\n"
                   1103: "serial number of your copy of COHERENT.\n\n"
                   1104:                        );
                   1105:                for (i = 1; i <= 3; i++) {
                   1106:                        s = get_line("Type in the serial number from the card:");
                   1107:                        if (isserial(s))
                   1108:                                break;
                   1109:                        if (i < 3)
                   1110:                                printf("Invalid serial number, please try again.\n");
                   1111:                        else
                   1112:                                fatal("invalid serial number");
                   1113:                }
                   1114:        }
                   1115: 
                   1116:        printf("\nRemoving old on-line COHERENT manual pages -- please wait...\n");
                   1117:        sys("/bin/rm -rf /mnt/usr/man/ALL /mnt/usr/man/COHERENT "
                   1118:            "/mnt/usr/man/MULTI /mnt/usr/man/man.tar*", S_NONFATAL);
                   1119:        sync();
                   1120: 
                   1121:        /*
                   1122:         * Save off any special files just in case the user wants to
                   1123:         * get the old ones back...
                   1124:         */
                   1125:        if (!is_dir("/mnt/old_coh")) {
                   1126:                printf(
                   1127: "\nSaving existing configuration files to directory /old_coh -- please wait...\n\n"
                   1128:                        );
                   1129:                sys("mkdir -r `cat /conf/upd_dirs`", S_NONFATAL);
                   1130:                sys(
                   1131: "for a in `cat /conf/upd_save` ;"
                   1132: " do ;"
                   1133: " cp -d /mnt/$a /mnt/old_coh/$a 2>/dev/null && echo $a... ;"
                   1134: " done ;"
                   1135: " echo", S_IGNORE);
                   1136:                sync();
                   1137:        } else
                   1138:                printf("Directory /old_coh contains configuration file backups.\n");
                   1139: 
                   1140: 
                   1141:        sprintf(cmd, "rm -f /mnt/coherent.* /mnt/drv/*");  /* rm stale copies */
                   1142:        sys(cmd, S_FATAL);
                   1143: 
                   1144:        sprintf(cmd, "/etc/umount %s", devname(root, 1));
                   1145:        sys(cmd, S_FATAL);
                   1146: 
                   1147: }
                   1148: 
                   1149: /*
                   1150:  * Date and time.
                   1151:  */
                   1152: void
                   1153: set_date()
                   1154: {
                   1155:        register char *s;
                   1156:        int dst_conv;           /* 1 if DST conversion will be used */
                   1157:        int dst_now;            /* 1 if DST in effect today */
                   1158:        int n;
                   1159:        char *tz;
                   1160:        time_t now;
                   1161:        struct tm *tmp;
                   1162:        char *timestr;
                   1163: 
                   1164: again:
                   1165: #if 1  /* new set_date */
                   1166: 
                   1167:        /*
                   1168:         * yyy:
                   1169:         *
                   1170:         * dst_conv = FALSE
                   1171:         * dst_now = FALSE
                   1172:         *
                   1173:         * if using DST conversion
                   1174:         *      dst_conv = TRUE
                   1175:         *      if DST in effect today
                   1176:         *              dst_now = TRUE
                   1177:         * get date from system clock
                   1178:         * if dst_conv and dst_now
                   1179:         *      add 1 hour to date fetched
                   1180:         * display date
                   1181:         * while date not correct
                   1182:         *      if proceed without setting clock
                   1183:         *              goto xxx
                   1184:         *      read date from kb
                   1185:         *      write date to CMOS clock and RAM clock
                   1186:         *      if dst_conv and dst_now
                   1187:         *              subtract 1 hour from date entered
                   1188:         *              write adjusted date to CMOS clock
                   1189:         * xxx:
                   1190:         * set TIMEZONE and TZ variables
                   1191:         * if date, TIMEZONE, and TZ not all correct
                   1192:         *      goto yyy
                   1193:         */
                   1194:        cls(0);
                   1195:        dst_conv = 0;
                   1196:        dst_now = 0;
                   1197:        printf(
                   1198: "You can run COHERENT with or without conversion for daylight savings time\n"
                   1199: "(summer time).  You should normally run with daylight savings time\n"
                   1200: "conversion.  However, if you are going to use both COHERENT and MS-DOS\n"
                   1201: "and you choose to run with daylight savings time conversion,\n"
                   1202: "your time will be wrong (by one hour) during daylight savings time\n"
                   1203: "while you are running under MS-DOS.\n"
                   1204: "\n"
                   1205:                );
                   1206:        if (yes_no(
                   1207:          "Do you want COHERENT to use daylight savings time conversion")) {
                   1208:                dst_conv = 1;
                   1209:                printf(
                   1210: "\n"
                   1211: "By default, COHERENT assumes daylight savings time begins on the\n"
                   1212: "first Sunday in April and ends on the last Sunday in October.\n"
                   1213: "If you want to change the defaults, edit the file \"/etc/timezone\"\n"
                   1214: "after you finish installing COHERENT.\n"
                   1215: "\n"
                   1216:                );
                   1217:                if (yes_no("Is daylight savings time currently in effect"))
                   1218:                        dst_now = 1;
                   1219:        }
                   1220:        sys("/bin/date `/etc/ATclock` > /dev/null", S_NONFATAL);
                   1221:        now = time(0);
                   1222:        if (dst_conv && dst_now)
                   1223:                now += 3600;
                   1224:        timestr = ctime(&now);
                   1225:        printf(
                   1226: "\nAccording to your system clock, your local date and time are:\n"
                   1227:        );
                   1228:        printf("%s\n", timestr);
                   1229:        if (!yes_no("Is this correct")) {
                   1230:                n = 0;
                   1231:                do {
                   1232:                        if (++n > 3) {
                   1233:                                printf(
                   1234: "The command which sets the internal real-time clock of your system is\n"
                   1235: "failing repeatedly.  Either you are entering the date and time incorrectly\n"
                   1236: "or your clock hardware is not completely AT-compatible.  If your clock\n"
                   1237: "hardware is incompatible, you can continue with the installation without\n"
                   1238: "setting the clock correctly.  However, if you do so, subsequent clock\n"
                   1239: "references (including file access and modification time information) will be\n"
                   1240: "incorrect and some commands (such as \"date\") will not function correctly.\n"
                   1241:                                        );
                   1242:                                if (yes_no("Do you want to proceed without setting the clock correctly"))
                   1243:                                        break;
                   1244:                                n = 0;
                   1245:                        }
                   1246:                        s = get_line(
                   1247: "\nEnter the correct date and time in the form YYMMDDHHMM.SS:"
                   1248:                                );
                   1249:                        sprintf(cmd, "/etc/ATclock %s >/dev/null", s);
                   1250:                } while (sys(cmd, S_NONFATAL) != 0);
                   1251:                sys("/bin/date `/etc/ATclock` >/dev/null", S_NONFATAL);
                   1252: 
                   1253:                if (dst_conv && dst_now) {
                   1254:                        /* Adjust for DST: set hardware clock back one hour. */
                   1255:                        now = time(0) - 3600;
                   1256:                        tmp = localtime(&now);
                   1257:                        sprintf(cmd,
                   1258:                          "/etc/ATclock %02d%02d%02d%02d%02d.%02d >/dev/null",
                   1259:                          tmp->tm_year, tmp->tm_mon + 1, tmp->tm_mday,
                   1260:                          tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
                   1261:                        sys(cmd, S_NONFATAL);
                   1262:                }
                   1263: 
                   1264:        }
                   1265: 
                   1266:        /* Timezone. */
                   1267:        cls(0);
                   1268:        printf(
                   1269: "Please choose one of the following timezones:\n"
                   1270: "\t0\tCentral European\n"
                   1271: "\t1\tGreenwich\n"
                   1272: "\t2\tNewfoundland\n"
                   1273: "\t3\tAtlantic\n"
                   1274: "\t4\tEastern\n"
                   1275: "\t5\tCentral\n"
                   1276: "\t6\tMountain\n"
                   1277: "\t7\tPacific\n"
                   1278: "\t8\tYukon\n"
                   1279: "\t9\tAlaska\n"
                   1280: "\t10\tBering\n"
                   1281: "\t11\tHawaii\n"
                   1282: "\t12\tOther\n"
                   1283:                );
                   1284:        do {
                   1285:                s = get_line("Timezone code:");
                   1286:        } while ((n = atoi(s)) < 0 || n > 12);
                   1287:        switch (n) {
                   1288:        /* N.B. entries truncated at tz[8] below if !dst_conv. */
                   1289:        case 0:         tz = "EST:-60:EDT:1.1.4";       break;
                   1290:        case 1:         tz = "GMT:000:GDT:1.1.4";       break;
                   1291:        case 2:         tz = "NST:210:NDT:1.1.4";       break;
                   1292:        case 3:         tz = "AST:240:ADT:1.1.4";       break;
                   1293:        case 4:         tz = "EST:300:EDT:1.1.4";       break;
                   1294:        case 5:         tz = "CST:360:CDT:1.1.4";       break;
                   1295:        case 6:         tz = "MST:420:MDT:1.1.4";       break;
                   1296:        case 7:         tz = "PST:480:PDT:1.1.4";       break;
                   1297:        case 8:         tz = "YST:540:YDT:1.1.4";       break;
                   1298:        case 9:         tz = "AST:600:ADT:1.1.4";       break;
                   1299:        case 10:        tz = "BST:660:BDT:1.1.4";       break;
                   1300:        case 11:        tz = "HST:600:HDT:1.1.4";       break;
                   1301:        case 12:        tz = NULL;                      break;
                   1302:        }
                   1303: 
                   1304:        if (tz == NULL)
                   1305:                get_timezone(dst_conv);
                   1306:        else {
                   1307:                strcpy(tzone, tz);
                   1308:                if (dst_conv) {
                   1309:                        /* for TZ, AST:240:ADT becomes AST4ADT */
                   1310:                        sprintf(tzone5, "%.3s%d%cDT",
                   1311:                          tz, atoi(tzone + 4)/60, tz[0]);
                   1312:                } else {
                   1313:                        /* for TZ, AST:240 becomes AST4 */
                   1314:                        sprintf(tzone5, "%.3s%d", tz, atoi(tzone + 4)/60);
                   1315:                        tzone[8] = '\0';
                   1316:                }
                   1317:        }
                   1318:        /* Done, print current time and retry if user botched it. */
                   1319:        printf("\nYour current local date and time are now:\n");
                   1320:        sprintf(cmd, "TIMEZONE='%s' /bin/date -s `/etc/ATclock`", tzone);
                   1321:        sys(cmd, S_NONFATAL);
                   1322: 
                   1323:        /* Write the timezone to /tmp/timezone for debug */
                   1324:        sprintf(cmd, "/bin/echo export TIMEZONE=\\\"%s\\\" >/tmp/timezone", tzone);
                   1325:        sys(cmd, S_NONFATAL);
                   1326:        sprintf(cmd, "/bin/echo export TZ=\\\"%s\\\" >>/tmp/timezone", tzone5);
                   1327:        sys(cmd, S_NONFATAL);
                   1328: #else
                   1329:        cls(0);
                   1330:        /* Get correct local time, set system time accordingly. */
                   1331:        printf(
                   1332: "It is important for the COHERENT system to know the correct date and time.\n"
                   1333: "You must provide information about your timezone and daylight savings time.\n"
                   1334: "\n"
                   1335: "According to your computer system clock, your current local date and time are:\n"
                   1336:                );
                   1337:        sys("/bin/date `/etc/ATclock`", S_NONFATAL);
                   1338:        if (!yes_no("Is this correct")) {
                   1339:                n = 0;
                   1340:                do {
                   1341:                        if (++n > 3) {
                   1342:                                printf(
                   1343: "The command which sets the internal real-time clock of your system is\n"
                   1344: "failing repeatedly.  Either you are entering the date and time incorrectly\n"
                   1345: "or your clock hardware is not completely AT-compatible.  If your clock\n"
                   1346: "hardware is incompatible, you can continue with the installation without\n"
                   1347: "setting the clock correctly.  However, if you do so, subsequent clock\n"
                   1348: "references (including file access and modification time information) will be\n"
                   1349: "incorrect and some commands (such as \"date\") will not function correctly.\n"
                   1350:                                        );
                   1351:                                if (yes_no("Do you want to proceed without setting the clock correctly"))
                   1352:                                        break;
                   1353:                                n = 0;
                   1354:                        }
                   1355:                        s = get_line(
                   1356: "Enter the correct date and time in the form YYMMDDHHMM.SS:"
                   1357:                                );
                   1358:                        sprintf(cmd, "/etc/ATclock %s >/dev/null", s);
                   1359:                } while (sys(cmd, S_NONFATAL) != 0);
                   1360:                sys("/bin/date `/etc/ATclock` >/dev/null", S_NONFATAL);
                   1361:        }
                   1362: 
                   1363:        /* DST. */
                   1364:        cls(0);
                   1365:        printf(
                   1366: "You can run COHERENT with or without conversion for daylight savings time\n"
                   1367: "(summer time).  You should normally run with daylight savings time\n"
                   1368: "conversion.  However, if you are going to use both COHERENT and MS-DOS\n"
                   1369: "and you choose to run with daylight savings time conversion,\n"
                   1370: "your time will be wrong (by one hour) during daylight savings time\n"
                   1371: "while you are running under MS-DOS.\n"
                   1372: "\n"
                   1373:                );
                   1374:        dst_conv = yes_no("Do you want COHERENT to use daylight savings time conversion");
                   1375:        if (dst_conv) {
                   1376:                printf(
                   1377: "\n"
                   1378: "By default, COHERENT assumes daylight savings time begins on the\n"
                   1379: "first Sunday in April and ends on the last Sunday in October.\n"
                   1380: "If you want to change the defaults, edit the file \"/etc/timezone\"\n"
                   1381: "after you finish installing COHERENT.\n"
                   1382: "\n"
                   1383:                        );
                   1384:                if (yes_no("Is daylight savings time currently in effect")) {
                   1385:                        /* Adjust for DST: set hardware clock back one hour. */
                   1386:                        now = time(NULL) - 60 * 60;
                   1387:                        tmp = localtime(&now);
                   1388:                        sprintf(cmd, "/etc/ATclock %02d%02d%02d%02d%02d.%02d >/dev/null",
                   1389:                                tmp->tm_year, tmp->tm_mon + 1, tmp->tm_mday,
                   1390:                                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
                   1391:                        sys(cmd, S_NONFATAL);
                   1392:                }
                   1393:        }
                   1394: 
                   1395:        /* Timezone. */
                   1396:        cls(0);
                   1397:        printf(
                   1398: "Please choose one of the following timezones:\n"
                   1399: "\t0\tCentral European\n"
                   1400: "\t1\tGreenwich\n"
                   1401: "\t2\tNewfoundland\n"
                   1402: "\t3\tAtlantic\n"
                   1403: "\t4\tEastern\n"
                   1404: "\t5\tCentral\n"
                   1405: "\t6\tMountain\n"
                   1406: "\t7\tPacific\n"
                   1407: "\t8\tYukon\n"
                   1408: "\t9\tAlaska\n"
                   1409: "\t10\tBering\n"
                   1410: "\t11\tHawaii\n"
                   1411: "\t12\tOther\n"
                   1412:                );
                   1413:        do {
                   1414:                s = get_line("Timezone code:");
                   1415:        } while ((n = atoi(s)) < 0 || n > 12);
                   1416:        switch (n) {
                   1417:        /* N.B. entries truncated at tz[8] below if !dst_conv. */
                   1418:        case 0:         tz = "EST:-60:EDT:1.1.4";       break;
                   1419:        case 1:         tz = "GMT:000:GDT:1.1.4";       break;
                   1420:        case 2:         tz = "NST:210:NDT:1.1.4";       break;
                   1421:        case 3:         tz = "AST:240:ADT:1.1.4";       break;
                   1422:        case 4:         tz = "EST:300:EDT:1.1.4";       break;
                   1423:        case 5:         tz = "CST:360:CDT:1.1.4";       break;
                   1424:        case 6:         tz = "MST:420:MDT:1.1.4";       break;
                   1425:        case 7:         tz = "PST:480:PDT:1.1.4";       break;
                   1426:        case 8:         tz = "YST:540:YDT:1.1.4";       break;
                   1427:        case 9:         tz = "AST:600:ADT:1.1.4";       break;
                   1428:        case 10:        tz = "BST:660:BDT:1.1.4";       break;
                   1429:        case 11:        tz = "HST:600:HDT:1.1.4";       break;
                   1430:        case 12:        tz = NULL;                      break;
                   1431:        }
                   1432: 
                   1433:        if (tz == NULL)
                   1434:                get_timezone(dst_conv);
                   1435:        else {
                   1436:                strcpy(tzone, tz);
                   1437:                if (!dst_conv)
                   1438:                        tzone[8] = '\0';
                   1439:        }
                   1440: 
                   1441:        /* Done, print current time and retry if user botched it. */
                   1442:        printf("\nYour current local date and time are now:\n");
                   1443:        sprintf(cmd, "TIMEZONE='%s' /bin/date -s `/etc/ATclock`", tzone);
                   1444:        sys(cmd, S_NONFATAL);
                   1445: #endif /* new set_date */
                   1446:        if (!yes_no("Is this correct"))
                   1447:                goto again;
                   1448: }
                   1449: 
                   1450: /*
                   1451:  * Configure user devices.
                   1452:  * Assumes hard disk filesystem mounted on /mnt.
                   1453:  * Write lines to /etc/mount.all, /etc/umount.all to [u]mount the user devices.
                   1454:  */
                   1455: void
                   1456: user_devices()
                   1457: {
                   1458:        register int i, status;
                   1459:        register char *s, *s2, *name, *rname;
                   1460: 
                   1461:        if (ncohdev == 1) {
                   1462:                sys("/bin/echo /dev/root >>/mnt/etc/checklist", S_NONFATAL);
                   1463:                return;
                   1464:        }
                   1465: 
                   1466:        /* Create user device names. */
                   1467:        cls(0);
                   1468:        printf(
                   1469: "Your system includes %d partition%s in addition to the root partition.\n"
                   1470: "These partitions are usually mounted on directories in the COHERENT\n"
                   1471: "root filesystem when the system goes into multiuser mode.\n"
                   1472: "For example, one non-root partition might be mounted on\n"
                   1473: "directory \"/u\", another on \"/v\", and so on.\n"
                   1474: "You now may specify where you want each partition mounted.\n",
                   1475:                ncohdev - 1, ncohdev == 2 ? "" : "s");
                   1476:        for (i = 0; i < ndevices; i++) {
                   1477:                if (notflag(i, F_COH) || notflag(i, F_FS) || isflag(i, F_ROOT))
                   1478:                        continue;
                   1479:                name = devname(i, 0);
                   1480:                rname = rawname(i, 0);
                   1481:                printf("\nPartition %d (%s):\n", i, name);
                   1482:                if (yes_no("Do you want %s mounted", name)) {
                   1483:                        setflag(i, F_MOUNT);
                   1484: again:
                   1485:                        s = get_line("Where do you want to mount it?");
                   1486:                        if (*s != '/') {
                   1487:                                printf("Type a directory name beginning with '/', such as \"/u\".\n");
                   1488:                                goto again;
                   1489:                        } else if ((s2 = strchr(s, ' ')) != NULL)
                   1490:                                *s2 = '\0';
                   1491:                        sprintf(cmd, "/mnt/%s", s);
                   1492:                        if ((status = is_dir(cmd)) == -1) {
                   1493:                                printf("%s exists but is not a directory.\n", s);
                   1494:                                goto again;
                   1495:                        } else if (status == 1) {
                   1496:                                strcpy(buf2, s);
                   1497:                                printf("Directory %s already exists.\n", s);
                   1498:                                if (!yes_no("Are you sure you want %s mounted on %s", name, s))
                   1499:                                        goto again;
                   1500:                                s = buf;
                   1501:                                strcpy(s, buf2);
                   1502:                        } else {
                   1503:                                /* Make the target directory, uid=bin, gid=bin. */
                   1504:                                sprintf(cmd, "/bin/mkdir -r /mnt%s", s);
                   1505:                                if (sys(cmd, S_NONFATAL))
                   1506:                                        goto again;
                   1507:                                sprintf(cmd, "/bin/chown bin /mnt%s", s);
                   1508:                                sys(cmd, S_NONFATAL);
                   1509:                                sprintf(cmd, "/bin/chgrp bin /mnt%s", s);
                   1510:                                sys(cmd, S_NONFATAL);
                   1511:                        }
                   1512:                        printf("%s will be mounted on %s when COHERENT goes multiuser.\n",
                   1513:                                name, s);
                   1514: 
                   1515:                        /* Change e.g. /usr/src to usr_src. */
                   1516:                        strcpy(buf2, &s[1]);
                   1517:                        while ((s2 = strchr(buf2, '/')) != NULL)
                   1518:                                *s2 = '_';
                   1519: 
                   1520:                        /* Make link to pseudo-device, e.g. "/dev/usr_src". */
                   1521:                        sprintf(cmd, "/mnt/dev/%s", buf2);
                   1522:                        if (exists(cmd))
                   1523:                                status = 1;             /* use normal name */
                   1524:                        else {
                   1525:                                sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/%s",
                   1526:                                        name, buf2);
                   1527:                                if ((status = sys(cmd, S_NONFATAL)) == 0)
                   1528:                                        printf(
                   1529: "/dev/%s is linked to %s to provide a mnemonic device name.\n",
                   1530:                                                buf2, name);
                   1531:                        }
                   1532: 
                   1533:                        /* Add lines to /etc/mount.all, /etc/umount.all. */
                   1534:                        if (status == 0)
                   1535:                                sprintf(cmd, "/bin/echo /etc/mount /dev/%s %s >>/mnt/etc/mount.all",
                   1536:                                        buf2, s);
                   1537:                        else
                   1538:                                sprintf(cmd, "/bin/echo /etc/mount %s %s >>/mnt/etc/mount.all",
                   1539:                                        name, s);
                   1540:                        sys(cmd, S_NONFATAL);
                   1541:                        if (status == 0)
                   1542:                                sprintf(cmd, "/bin/echo /etc/umount /dev/%s >>/mnt/etc/umount.all",
                   1543:                                        buf2);
                   1544:                        else
                   1545:                                sprintf(cmd, "/bin/echo /etc/umount %s >>/mnt/etc/umount.all",
                   1546:                                        name);
                   1547:                        sys(cmd, S_NONFATAL);
                   1548: 
                   1549:                        /* And again, for the raw device. */
                   1550:                        sprintf(cmd, "/mnt/dev/r%s", buf2);
                   1551:                        if (exists(cmd))
                   1552:                                status = 1;
                   1553:                        else {
                   1554:                                sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/r%s",
                   1555:                                        rname, buf2);
                   1556:                                if ((status = sys(cmd, S_NONFATAL)) == 0)
                   1557:                                        printf(
                   1558: "/dev/r%s is linked to %s to provide a mnemonic device name.\n",
                   1559:                                                buf2, rname);
                   1560:                        }
                   1561: 
                   1562:                        /* Add raw device line to /etc/checklist. */
                   1563:                        if (status == 0)
                   1564:                                sprintf(cmd, "/bin/echo /dev/r%s >>/mnt/etc/checklist",
                   1565:                                        buf2);
                   1566:                        else
                   1567:                                sprintf(cmd, "/bin/echo %s >>/mnt/etc/checklist",
                   1568:                                        rname);
                   1569:                        sys(cmd, S_NONFATAL);
                   1570:                } else {
                   1571:                        /* Not mounted, check using standard name. */
                   1572:                        sprintf(cmd, "/bin/echo %s >>/mnt/etc/checklist", rname);
                   1573:                        sys(cmd, S_NONFATAL);
                   1574:                }
                   1575:        }
                   1576:        sys("/bin/echo /dev/root >>/mnt/etc/checklist", S_NONFATAL);
                   1577: 
                   1578:        /* Link /dev/dos if desired. */
                   1579:        if (yes_no("Do you use both COHERENT and MS-DOS on your hard disk")) {
                   1580:                i = get_int(0, ndevices-1, "Enter the partition number of your MS-DOS partition:");
                   1581:                sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/dos", devname(i, 0));
                   1582:                if (sys(cmd, S_NONFATAL) == 0)
                   1583:                        printf(
                   1584: "Device name /dev/dos is now linked to %s for use as a mnemonic\n"
                   1585: "device name.  You may use the \"dos*\" family of commands to transfer files\n"
                   1586: "to and from the MS-DOS partition on your hard disk as well as MS-DOS floppies.\n",
                   1587:                                devname(i, 0));
                   1588:                printf("\n");
                   1589:        }
                   1590: }
                   1591: 
                   1592: 
                   1593: /*
                   1594:  * Set up site/machine specific info in files /etc/uucpname and /etc/domain
                   1595:  */
                   1596: void
                   1597: uucp()
                   1598: {
                   1599:        unsigned char *cp;
                   1600: 
                   1601:        cls(1);
                   1602:        if (!update || !exists_and_nz("/mnt/etc/uucpname")) {
                   1603:                printf(
                   1604: "In order to use COHERENT's electronic mail facility and UUCP subsystem,\n"
                   1605: "you must choose a \"site name\" for your computer system.  In general, a site\n"
                   1606: "name consists of lower case letters or digits and should be at most seven\n"
                   1607: "characters in length.  The name you choose should be unique if you intend\n"
                   1608: "to access any other computer systems.  Some of the more well known site\n"
                   1609: "names include \"mwc\", \"uunet\", \"clout\", \"decwrl\", \"hp\", \"kgbvax\", "
                   1610: "\"prep\",\n\"seismo\", and \"ucbvax\".\n\n"
                   1611:                );
                   1612:                for (;;) {
                   1613:                        cp = get_line("Please enter the site name for this system: ");
                   1614:                        if (ok_name(cp, 'u'))
                   1615:                                break;
                   1616:                }
                   1617:                sprintf(cmd, "/bin/echo \"%s\" >/mnt/etc/uucpname", cp);
                   1618:                sys(cmd, S_NONFATAL);
                   1619:        }
                   1620: 
                   1621:        if (!update || !exists_and_nz("/mnt/etc/domain")) {
                   1622:                printf(
                   1623: "\nThe COHERENT mail subsystem supports \"domain addressing\" in addition to\n"
                   1624: "traditional \"bang paths\".  Until your system becomes part of a registered\n"
                   1625: "domain, you may use the UUCP pseudo-domain.  Domain names consist of groups\n"
                   1626: "of letters and digits separated by periods (dots).  Some of the more well\n"
                   1627: "known domains include \"com\", \"edu\", \"gov\", \"org\", \"net\", as well as domains\n"
                   1628: "covering a geographical area, such as the Chicago area \"chi.il.us\" domain.\n"
                   1629: "If you are not registered in a domain, or if you are uncertain about this\n"
                   1630: "question, simply press the <Enter> key to default to the UUCP pseudo-domain.\n\n"
                   1631:                );
                   1632:                for (;;) {
                   1633:                        cp = get_line("Please enter the domain name for this system: ");
                   1634:                        if (ok_name(cp, 'd'))
                   1635:                                break;
                   1636:                }
                   1637:                sprintf(cmd, "/bin/echo \"%s\" >/mnt/etc/domain", cp);
                   1638:                sys(cmd, S_NONFATAL);
                   1639:        }
                   1640: }
                   1641: 
                   1642: /*
                   1643:  * Hi there.
                   1644:  */
                   1645: void
                   1646: welcome()
                   1647: {
                   1648:        register char *s;
                   1649:        int i;
                   1650: 
                   1651:        cls(0);
                   1652:        printf(
                   1653: "\n\n\n\n\n\n\n\n"
                   1654: "                              The COHERENT System\n\n"
                   1655: "                Copyright (c) 1982, 1992 by Mark Williams Company\n\n"
                   1656: "                     60 Revere Drive, Northbrook, IL  60062\n\n"
                   1657: "                        708-291-6700, 708-291-6750 (FAX)\n"
                   1658: "\n\n\n\n\n\n"
                   1659:                );
                   1660: 
                   1661:        cls(1);
                   1662:        printf(
                   1663: "Welcome to the COHERENT operating system!\n\n"
                   1664: "Your computer is now running COHERENT "
                   1665: "386"
                   1666: " from the floppy disk.\n");
                   1667:        if (update)
                   1668:                printf(
                   1669: "This program will update your existing COHERENT 4.0.x system to COHERENT 4.2.0.\n"
                   1670: "\n"
                   1671: "Be sure to read the section on \"Updating\" in the COHERENT 386 Release\n"
                   1672: "Notes prior to attempting this update!\n\n"
                   1673: "Please be patient and read the instructions on the screen carefully.\n"
                   1674: "\n"
                   1675:                        );
                   1676:        else
                   1677:                printf(
                   1678: "This program will install COHERENT onto your hard disk.\n"
                   1679: "\n"
                   1680: "If you are already running COHERENT on your hard disk, you must perform an\n"
                   1681: "update rather than a full installation.  To do so, please REBOOT NOW and\n"
                   1682: "follow the detailed update instructions in the COHERENT release notes supplied\n"
                   1683: "with this release.\n"
                   1684: "\n"
                   1685: "You can interrupt installation at any time by typing <Ctrl-C>;\n"
                   1686: "then reboot and start the installation procedure again.\n"
                   1687: "Please be patient and read the instructions on the screen carefully.\n"
                   1688: "\n"
                   1689:                        );
                   1690:        cls(1);
                   1691:        if (update)
                   1692:                sys("/etc/kbdinstall -u", S_NONFATAL);
                   1693:        else
                   1694:                sys("/etc/kbdinstall -b", S_NONFATAL);
                   1695: 
                   1696:        cls(1);
                   1697:        if (!update) {
                   1698:                printf(
                   1699: "A card included with your distribution gives the serial number\n"
                   1700: "of your copy of COHERENT.\n"
                   1701:                        );
                   1702:                for (i = 1; i <= 3; i++) {
                   1703:                        s = get_line("Type in the serial number from the card:");
                   1704:                        if (isserial(s))
                   1705:                                return;
                   1706:                        printf("Invalid serial number, please try again.\n");
                   1707:                }
                   1708:                fatal("invalid serial number");
                   1709:        }
                   1710: }
                   1711: 
                   1712: /*
                   1713:  * Generate a partition table device name from a DEVICE entry name.
                   1714:  * Return a pointer to the statically allocated name.
                   1715:  * If flag and not one of the built-in AT device names,
                   1716:  * the device is in /tmp/dev rather than /dev.
                   1717:  */
                   1718: char *
                   1719: xname(i, flag) int i, flag;
                   1720: {
                   1721:        static char xname[4+4+1+NAMESIZE];      /* e.g. "/tmp/dev/at0x" */
                   1722: 
                   1723:        sprintf(xname, "/tmp/dev/%s", devices[i].d_xname);
                   1724:        return (flag && notflag(i,  F_ATDEV)) ? xname : xname+4;
                   1725: }
                   1726: 
                   1727: /* end of build.c */

unix.superglobalmegacorp.com

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