|
|
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:
90: DEVICE devices[NDEVICES];
91:
92: #if 0
93:
94: /* get rid of this... this makes fdisk ALWAYS try to open 2 AT drives even
95: * if only one or none are present.
96: * Bob H. (8/10/93)
97: */
98: /*
99: * Device table.
100: * add_devices() adds entries for devices created by /etc/mkdev.
101: * fdisk() zaps the entries for which the xdevice open fails.
102: */
103: DEVICE devices[NDEVICES] = {
104: { "at0x", "at0a", AT_MAJOR, 0, F_ATDEV, 0L },
105: { "at0x", "at0b", AT_MAJOR, 1, F_ATDEV, 0L },
106: { "at0x", "at0c", AT_MAJOR, 2, F_ATDEV, 0L },
107: { "at0x", "at0d", AT_MAJOR, 3, F_ATDEV, 0L },
108: { "at1x", "at1a", AT_MAJOR, 4, F_ATDEV, 0L },
109: { "at1x", "at1b", AT_MAJOR, 5, F_ATDEV, 0L },
110: { "at1x", "at1c", AT_MAJOR, 6, F_ATDEV, 0L },
111: { "at1x", "at1d", AT_MAJOR, 7, F_ATDEV, 0L }
112: };
113:
114: #endif /* 0 */
115:
116:
117: /* Externals. */
118: extern long atol();
119: extern char *fgets();
120: extern long lseek();
121: extern time_t time();
122:
123: /* Forward. */
124: void add_devices();
125: void badscan();
126: void copy();
127: char *devname();
128: void done();
129: int exists_and_nz();
130: void fdisk();
131: int is_fs();
132: void mkdev();
133: void mkfs();
134: void new_boot();
135: void patches();
136: char *protoname();
137: char *rawname();
138: void rootpatch();
139: void save_files();
140: void user_devices();
141: void welcome();
142: char *xname();
143:
144: /* Globals. */
145: int active = -1; /* active partition */
146: char *activeos; /* active partition OS */
147: char buf2[NBUF]; /* extra buffer */
148: HDISK_S hd; /* hard disk boot block */
149: int mboot; /* mboot replaced */
150: int ncohdev; /* number of COHERENT devices */
151: int ndevices = 0; /* number of devices */
152: int protoflag; /* prototypes created */
153: int root; /* root partition */
154: char tzone[NBUF]; /* timezone */
155: char tzone5[NBUF]; /* timezone for Sys V */
156: int update; /* update, rather than install */
157:
158: main(argc, argv) int argc; char *argv[];
159: {
160: register char *s;
161:
162: argv0 = argv[0];
163: abortmsg = 1;
164: usagemsg = USAGE;
165: if (argc > 1 && argv[1][0] == '-') {
166: for (s = &argv[1][1]; *s; ++s) {
167: switch(*s) {
168: case 'd': ++dflag; break;
169: case 'u': ++update; break;
170: case 'v': ++vflag; break;
171: case 'V':
172: fprintf(stderr, "%s: V%s\n", argv0, VERSION);
173: break;
174: default: usage(); break;
175: }
176: }
177: --argc;
178: ++argv;
179: }
180: if (argc != 1)
181: usage();
182:
183: welcome();
184: mkdev();
185:
186: fdisk();
187: if (update) {
188: new_boot(); /* write out new boot block for tboot */
189: save_files();
190: } else {
191: badscan();
192: mkfs();
193: }
194: copy();
195:
196: if (!update)
197: user_devices();
198:
199: rootpatch();
200: patches();
201: sys("/bin/echo /etc/build: success >>/mnt/etc/install.log", S_NONFATAL);
202: sprintf(cmd, "TIMEZONE=\"%s\" /bin/date >>/mnt/etc/install.log", tzone);
203: sys(cmd, S_NONFATAL);
204: sys("/bin/echo >>/mnt/etc/install.log", S_NONFATAL);
205: sprintf(cmd, "/etc/umount %s", devname(root, 1));
206: sync();
207: sys(cmd,S_NONFATAL);
208: done();
209: sys("/etc/reboot -p", S_IGNORE);
210:
211: /* NOTREACHED */
212: exit(0);
213: }
214:
215: /*
216: * Append devices as specified by /etc/mkdev to devices table.
217: */
218: void
219: add_devices()
220: {
221: register FILE *fp;
222: register int i, n;
223:
224: if ((fp = fopen(DEVICE_FILE, "r")) == NULL)
225: return;
226:
227: for (i = ndevices; i < NDEVICES; i++) {
228: n = fscanf(fp, "%s %s %d %d\n",
229: devices[i].d_xname, devices[i].d_dname,
230: &devices[i].d_major, &devices[i].d_minor);
231: if (n == 0 || n == EOF)
232: break;
233: else if (n != 4)
234: fatal("scanf failed on %s, n=%d", DEVICE_FILE, n);
235: ++ndevices;
236: }
237: if (i == NDEVICES)
238: nonfatal("too many devices, excess ignored");
239:
240: fclose(fp);
241: }
242:
243: /*
244: * Scan each COHERENT device for bad blocks.
245: */
246: void
247: badscan()
248: {
249: register int i;
250: register char *name;
251:
252: cls(1);
253: printf(
254: "The next step in installation is to scan each COHERENT partition\n"
255: "for bad blocks. This will not write to the partition being scanned.\n"
256: "Be patient. This takes a few minutes.\n"
257: );
258: for (i = 0; i < ndevices; i++) {
259: if (notflag(i, F_COH) || notflag(i, F_ATDEV))
260: continue; /* scan only AT device COH partitions */
261: printf("\n");
262: name = devname(i, 0);
263: if (isflag(i, F_FS)) {
264: printf(
265: "Partition %d (%s) already contains a COHERENT filesystem.\n"
266: "If you wish to continue to use the existing filesystem, you can skip\n"
267: "scanning it for bad blocks. If you want to replace it with an empty\n"
268: "filesystem, you must scan it for bad blocks first.\n",
269: i, name);
270: if (yes_no("Do you want to scan %s for bad blocks",
271: name) == 0)
272: continue;
273: }
274: printf("Scanning partition %d:\n", i);
275: setflag(i, F_SCAN);
276: sprintf(cmd, "/etc/badscan -v -o %s %s %s",
277: protoname(i), rawname(i, 1), xname(i, 1));
278: if (sys(cmd, S_NONFATAL) == 0) {
279: setflag(i, F_PROTO);
280: ++protoflag;
281: }
282: }
283: }
284:
285: /*
286: * Mount the root filesystem, copy files to it, patch /coherent.
287: * Kludge around as required.
288: */
289: void
290: copy()
291: {
292: cls(0);
293: printf(
294: "The next step is to copy some COHERENT files from the diskette to the\n"
295: "root filesystem of your hard disk. This will take a few minutes...\n"
296: );
297:
298: /* Mount the filesystem. */
299: sprintf(cmd, "/etc/mount %s /mnt", devname(root, 1));
300:
301: sys(cmd, S_FATAL);
302:
303: if(update){
304: printf(
305: "The existing /coherent kernel on the root file system will now be renamed to\n"
306: "coh.B4.420. After this the remainder of diskette #1 will be copied.\n\n"
307: );
308:
309: /* move the existing kernel names /coherent to coh.B4.420 */
310: sprintf(cmd,"/bin/cp /mnt/coherent /mnt/coh.B4.420 2>/dev/null");
311: sys(cmd,S_NONFATAL);
312: }
313:
314: /* Copy the boot floppy. */
315: sprintf(cmd, "/bin/cpdir -ad%s -smnt -sbegin -stmp %s / /mnt",
316: (vflag) ? "v" : "", (update) ? "`cat /conf/upd_suppress`" : "");
317: sys(cmd, S_FATAL);
318:
319: /* Copy idtune and idenable data files. */
320: sprintf(cmd, "/bin/cp %s %s /mnt/conf", IDCMDFILE, IDVARFILE);
321: sys(cmd, S_FATAL);
322:
323: /* Copy patch file for debugging. */
324: sprintf(cmd, "/bin/cp %s /mnt/conf", PATCHFILE);
325: sys(cmd, S_FATAL);
326:
327: if (!is_dir("/mnt/mnt"))
328: sys("/bin/mkdir /mnt/mnt", S_FATAL);
329: sys("/bin/chmog 0755 bin bin /mnt/mnt", S_NONFATAL);
330:
331: /* Write entry to /etc/install.log. */
332: sprintf(cmd, "/bin/echo /etc/build: %s %s >>/mnt/etc/install.log",
333: "386",
334: (update) ? "update" : "install");
335: sys(cmd, S_NONFATAL);
336: sprintf(cmd, "TIMEZONE=\"%s\" /bin/date >>/mnt/etc/install.log", tzone);
337: sys(cmd, S_NONFATAL);
338:
339: /* If /etc/mkdev created devices in /tmp/dev, copy them to /dev. */
340: /* Remove the copies in /tmp/dev on the hard disk. */
341: if (exists("/tmp/dev"))
342: sys("/bin/cpdir -d /tmp/dev /mnt/dev", S_FATAL);
343: if (exists("/tmp/drvld.all")) {
344: sys("/bin/cp /tmp/drvld.all /mnt/etc/drvld.all", S_NONFATAL);
345: sys("/bin/chmog 0744 root root /mnt/etc/drvld.all", S_NONFATAL);
346: }
347:
348: sys("/bin/cat /tmp/ttys >>/mnt/etc/ttys", S_NONFATAL);
349: sys("/bin/cp /tmp/id-cmd /mnt/etc/conf/bin/id-cmd", S_NONFATAL);
350: sys("/bin/chmog 544 root root /mnt/etc/conf/bin/id-cmd", S_NONFATAL);
351:
352: /* Grow /lost+found to make room for files. */
353: sys("cd /mnt/lost+found \n"
354: "/bin/touch `/bin/from 1 to 200` \n"
355: "/bin/rm *", S_IGNORE);
356:
357: /* Create /autoboot. */
358: sys("/bin/ln -f /mnt/coherent /mnt/autoboot", S_FATAL);
359:
360: /* Replace the build version of /etc/brc with the install version. */
361: sys("/bin/rm /mnt/etc/brc", S_NONFATAL);
362: if (update)
363: sys("/bin/ln -f /mnt/etc/brc.update /mnt/etc/brc", S_FATAL);
364: else
365: sys("/bin/ln -f /mnt/etc/brc.install /mnt/etc/brc", S_FATAL);
366:
367: /* Link root device to /dev/root. */
368: sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/root", devname(root, 0));
369: sys(cmd, S_FATAL);
370:
371: /* Write the timezone to /etc/timezone. */
372: sprintf(cmd, "/bin/echo export TIMEZONE=\\\"%s\\\" >/mnt/etc/timezone", tzone);
373: sys(cmd, S_NONFATAL);
374: sprintf(cmd, "/bin/echo export TZ=\\\"%s\\\" >>/mnt/etc/timezone", tzone5);
375: sys(cmd, S_NONFATAL);
376:
377:
378: /* If a mkdev file was created for tape devices for the hai driver,
379: * copy it to /etc/conf/hai/mkdev so that when the final kernel is
380: * finally built, the mkdev script will automatically be invoked to
381: * create the appropriate tape device nodes.
382: * Bob H. (August 13, 1993)
383: */
384:
385: if(exists("/tmp/haimkdev")){
386: sys("cp /tmp/haimkdev /mnt/etc/conf/hai/mkdev",S_NONFATAL);
387: }
388:
389: if (!update) {
390: /* Write the serial number to /etc/serialno. */
391: sprintf(cmd, "/bin/echo %s >/mnt/etc/serialno", serialno);
392: sys(cmd, S_NONFATAL);
393: }
394:
395: /* Save the prototypes from /tmp to /conf. */
396: if (protoflag)
397: sys("/bin/mv /tmp/*.proto /mnt/conf", S_NONFATAL);
398: }
399:
400: /*
401: * Generate a device name from a DEVICE entry name.
402: * Return a pointer to the statically allocated name.
403: * If flag and not one of the built-in AT device names,
404: * the device is in /tmp/dev rather than /dev.
405: * Sleazy hack: this always writes "/tmp/dev/..." in the buffer and
406: * massages the return value accordingly so that subsequent calls
407: * with same i but different flag will not clobber previous return values.
408: */
409: char *
410: devname(i, flag) int i, flag;
411: {
412: static char name[4+4+1+NAMESIZE]; /* e.g. "/tmp/dev/at0a" */
413:
414: #if 0
415: sprintf(name, "/tmp/dev/%s", devices[i].d_dname);
416: return (flag && notflag(i, F_ATDEV)) ? name : name+4;
417: #endif
418:
419: sprintf(name, "/dev/%s", devices[i].d_dname);
420: return (name);
421: }
422:
423: /*
424: * Done.
425: * Print useful information.
426: */
427: void
428: done()
429: {
430: cls(1);
431: printf(
432: "You have installed the COHERENT operating system onto your hard disk.\n"
433: "To install files from the remaining diskettes in the installation kit,\n"
434: "you must boot the COHERENT system from the hard disk. It will prompt\n"
435: "you to install the remaining diskettes in the installation kit.\n"
436: "\n"
437: "After you finish reading this information, remove the floppy disk,\n"
438: "hit <Enter> and your system will automatically reboot.\n"
439: "\n"
440: );
441: if (mboot) {
442: printf(
443: "If you type a partition number (0 to 7) while\n"
444: "the boot procedure is trying to read the floppy disk,\n"
445: "your system will boot the operating system on that partition.\n"
446: );
447: if (active != -1) {
448: printf("If you type nothing, your system will boot ");
449: if (active == root)
450: printf("COHERENT (partition %d).\n", active);
451: else {
452: printf("active partition %d", active);
453: if (activeos != NULL)
454: printf(" (%s)", activeos);
455: printf(".\n", active);
456: }
457: }
458: } else {
459: printf(
460: "You must boot the new COHERENT root filesystem on partition %d.\n",
461: root);
462: }
463:
464: sync();
465: printf(
466: "\nNow remove the floppy disk so your system does not boot from the floppy.\n");
467:
468: if (mboot && root != active)
469: printf(
470: "You MUST type %d when the system tries to read the floppy disk during the boot\n"
471: "procedure to boot the partition containing the new COHERENT root filesystem.\n",
472: root);
473: }
474:
475: /*
476: * See if the specified file exists and has non-zero length.
477: */
478: exists_and_nz(fn)
479: char *fn;
480: {
481: struct stat s;
482:
483: if (stat(fn, &s) == -1)
484: return 0; /* does not exist */
485: return (s.st_size > 0); /* exists and length > 0 */
486: }
487:
488: /*
489: * Get partition table information.
490: */
491: void
492: fdisk()
493: {
494: register int fd, i, j, n, part, cohpart, flag;
495: char *fname, *s;
496:
497: cls(1);
498: if (update) {
499: printf("Reading existing partition tables...\n");
500: } else {
501: printf(
502: "This installation procedure allows you to create one or more partitions\n"
503: "on your hard disk to contain the COHERENT system and its files.\n"
504: "Each disk drive may contain no more than four logical partitions.\n"
505: "If all four partitions on your disk are already in use, you will\n"
506: "have to overwrite at least one of them to install COHERENT.\n"
507: "If your disk uses fewer than four partitions and has enough unused space\n"
508: "for COHERENT (%d megabytes), you can install COHERENT into the unused space.\n"
509: "If you intend to install MS-DOS after installing COHERENT,\n"
510: "you must leave the first physical partition free for MS-DOS.\n"
511: "\n"
512: "The next part of the installation procedure will let you change the\n"
513: "partitions on your hard disk. Data on unchanged hard disk partitions\n"
514: "will not be changed. However, data already on your hard disk may be\n"
515: "destroyed if you change the base or the size of a logical partition,\n"
516: "or if you change the order of the partition table entries.\n"
517: "If you need to back up existing data from the hard disk,\n"
518: "type <Ctrl-C> now to interrupt COHERENT installation; then reboot your\n"
519: "system and back up your hard disk data onto diskettes.\n"
520: "\n", NEEDSIZE);
521: cls(1);
522: printf(
523: "COHERENT initialization normally writes a new master bootstrap program onto\n"
524: "your hard disk. The COHERENT master boot allows you to boot the operating\n"
525: "system on one selected disk partition (the active partition) automatically;\n"
526: "it also allows you to boot the operating system on any disk partition by\n"
527: "typing a key when you reboot. Mark Williams strongly recommends that you\n"
528: "use the COHERENT master boot. However, the COHERENT master boot may not\n"
529: "work with some operating systems (for example, Xenix) if you make the\n"
530: "COHERENT partition active; instead, leave the other partition (e.g. Xenix)\n"
531: "active and boot COHERENT by typing a key. If you do not use the COHERENT\n"
532: "bootstrap, you must understand how to boot the COHERENT partition using your\n"
533: "existing bootstrap program.\n"
534: "\n"
535: );
536: if (yes_no("Do you want to use the COHERENT master boot"))
537: ++mboot;
538:
539: retry:
540: /* Construct an /etc/fdisk command with appropriate xdevice names. */
541: strcpy(cmd, "/etc/fdisk -cB");
542: if (mboot)
543: strcat(cmd, "b /conf/mboot");
544:
545:
546: for (i = 0; i < ndevices; i++) {
547: if (i == 0
548: || strcmp(devices[i-1].d_xname, devices[i].d_xname) != 0) {
549: if ((fd = open(xname(i, 1), 0)) < 0){
550: continue;
551: }
552: close(fd);
553: strcat(cmd, " ");
554: strcat(cmd, xname(i, 1));
555: }
556: }
557: sys(cmd, S_FATAL); /* do the fdisk command */
558: } /* !update */
559:
560: /* Read the partition table and set device flags appropriately. */
561: for (i = part = 0; i < ndevices; ++i) {
562: if (i != 0
563: && strcmp(devices[i-1].d_xname, devices[i].d_xname) == 0)
564: continue; /* partition already done */
565: fname = xname(i, 1);
566: if ((fd = open(fname, 0)) < 0)
567: continue; /* cannot open xdevice */
568: if (read(fd, &hd, sizeof hd) != sizeof hd)
569: fatal("%s: read failed", fname);
570: close(fd);
571: if (hd.hd_sig != HDSIG) {
572: nonfatal("%s: invalid partition table", fname);
573: continue;
574: }
575: /* The partition table is valid, check its partitions. */
576: for (j = 0; j < NPARTN && i + j < ndevices; j++) {
577: n = i + j; /* index in devices[] */
578: if (part != n) {
579: /*
580: * Copy over unopenable partitions.
581: * This allows subsequent code to use
582: * the devices[] index as the partition number.
583: */
584: devices[part] = devices[n];
585: n = part;
586: }
587: part++; /* another valid partition */
588: if (hd.hd_partn[j].p_boot != 0) {
589: setflag(n, F_BOOT);
590: if (active == -1)
591: active = n; /* first active partition */
592: switch(hd.hd_partn[j].p_sys) {
593: case SYS_COH:
594: activeos = "COHERENT";
595: break;
596: case SYS_DOS_12:
597: case SYS_DOS_16:
598: case SYS_DOS_XP:
599: case SYS_DOS_LARGE:
600: activeos = "MS-DOS";
601: break;
602: case SYS_XENIX:
603: activeos = "Xenix";
604: break;
605: default:
606: activeos = NULL;
607: break;
608: }
609: }
610: if (hd.hd_partn[j].p_sys != SYS_COH)
611: continue;
612:
613: /* Make sure the device can be accessed. */
614: s = devname(n, 1);
615: if (!exists(s)) {
616: nonfatal("cannot open COHERENT partition %d (%s)",
617: n, devname(n, 0));
618: continue;
619: } else if (hd.hd_partn[j].p_size == 0L) {
620: nonfatal("COHERENT partition %d (%s) is empty",
621: j, devname(n, 0));
622: continue;
623: }
624:
625: /* OK, set flags in the device table. */
626: ++ncohdev;
627: setflag(n, F_COH);
628: devices[n].d_size = hd.hd_partn[j].p_size;
629: if (is_fs(s, devices[n].d_size))
630: setflag(n, F_FS);
631:
632: /* Make sure the device is not mounted. */
633: sprintf(cmd, "/etc/umount %s 2>/dev/null", s);
634: sys(cmd, S_IGNORE);
635: }
636: }
637: ndevices = part;
638: if (ndevices == 0)
639: fatal("cannot open partition tables");
640: else if (ncohdev == 0)
641: fatal("no COHERENT partition found");
642: cls(0);
643: printf("Your system includes %d COHERENT partition%s:\n",
644: ncohdev, (ncohdev == 1) ? "" : "s");
645: printf("Drive Partition\t Device\tMegabytes\n");
646: for (flag = i = 0; i < ndevices; i++)
647: if (isflag(i, F_COH)) {
648: cohpart = i;
649: printf("%3d\t%3d\t%s\t%.2f\n",
650: i/NPARTN,
651: i,
652: devname(i, 0),
653: meg(devices[i].d_size));
654: if (((int)meg(devices[i].d_size)) > MAXSIZE)
655: flag = 1;
656: }
657: if (!update && flag) {
658: printf(
659: "\n"
660: "Your system includes a large COHERENT filesystem (larger than %d megabytes).\n"
661: "You should repartition the hard disk to define smaller COHERENT partitions.\n",
662: MAXSIZE);
663: if (yes_no("Do you want to repartition the hard disk"))
664: goto retry;
665: printf("\n");
666: }
667:
668: if (ncohdev == 1) {
669: root = cohpart;
670: setflag(root, F_ROOT);
671: return;
672: }
673: printf(
674: "You must specify one COHERENT partition as the root filesystem.\n"
675: );
676: if (!update)
677: printf(
678: "The root filesystem contains the files normally used by COHERENT.\n"
679: "The root filesystem should contain at least %d megabytes.\n",
680: NEEDSIZE);
681: if (ndevices > ATDEVS)
682: printf(
683: "The COHERENT root filesystem must be on partition 0 through 7.\n"
684: );
685: if (active != -1 && isflag(active, F_COH)) {
686: printf("COHERENT partition %d is marked as active in the partition table.\n",
687: active);
688: if (!update)
689: printf(
690: "If you choose it as the root, you can boot COHERENT automatically.\n"
691: );
692: }
693: printf("\n");
694: again:
695: if (update)
696: s = get_line("Which partition contains the COHERENT root filesystem?");
697: else
698: s = get_line("Which partition do you want to be the root filesystem?");
699: root = *s - '0';
700: if (*++s != '\0' || root < 0 || root >= ATDEVS || notflag(root, F_COH)) {
701: printf("Enter a number between 0 and 7 which specifies a COHERENT partition.\n");
702: goto again;
703: }
704:
705: if (meg(devices[root].d_size) < (double)NEEDSIZE) {
706: if (update) {
707: printf(
708: "\n"
709: "Your current COHERENT 4.0.x root filesystem is too small to contain the\n"
710: "COHERENT 4.2.0 update along with the on-line manual pages and the on-line\n"
711: "dictionary. If you wish to have the COHERENT 4.2.0 on-line manual pages and\n"
712: "the on-line dictionary installed, you will need to do the following:\n\n"
713: "\t1) Exit from the update.\n"
714: "\t2) Boot from your existing COHERENT root partition.\n"
715: "\t3) Perform a full \"backup\" of ALL PARTITIONS on your hard disk\n"
716: "\t include all of your existing programs, files, and any system\n"
717: "\t files that you have modified using backup utilities \"cpio\",\n"
718: "\t \"ustar\", or \"tar\". If your hard disk includes partitions\n"
719: "\t assigned to other operating systems, be sure to back these up also!\n"
720: "\t4) Perform a full installation of COHERENT 386 using the same disks\n"
721: "\t supplied for the update. Note that you will need to increase the\n"
722: "\t size of the root partition, or you will need to select a different\n"
723: "\t partition to contain the root filesystem. Please refer to the\n"
724: "\t chapter on installation found in the COHERENT 386 release notes.\n"
725: );
726: sync();
727: if (yes_no("Do you wish to abort the update"))
728: fatal("Insufficient disk space for update!");
729: } else {
730: printf("Partition %d contains only %.2f megabytes.\n",
731: root, meg(devices[root].d_size));
732: if (meg(devices[root].d_size) < (double)MINSIZE) {
733: printf("It is too small to contain the COHERENT root filesystem.\n");
734: goto again;
735: }
736: if (!yes_no("Are you sure you want it to be the root partition"))
737: goto again;
738: }
739: }
740: setflag(root, F_ROOT);
741: }
742:
743: /*
744: * Check if a special file is a well-formed filesystem.
745: * This routine is derived from code in "mount.c".
746: * Here the check that "special" is a block special file is eliminated
747: * and the size is checked against the partition size.
748: */
749: int
750: is_fs(special, size) char *special; unsigned long size;
751: {
752: static struct filsys f;
753: register int fd;
754: register struct filsys *fp;
755: register daddr_t *dp;
756: register ino_t *ip, maxinode;
757:
758: if ((fd = open(special, 0)) < 0 /* cannot open */
759: || lseek(fd, (long)SUPERI*BSIZE, 0) == -1L /* seek failed */
760: || read(fd, &f, sizeof(f)) != sizeof(f)) /* read failed */
761: return 0;
762: close(fd);
763:
764: /* Canonical stuff. */
765: fp = &f;
766: canshort(fp->s_isize);
767: candaddr(fp->s_fsize);
768: canshort(fp->s_nfree);
769: for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
770: candaddr(*dp);
771: canshort(fp->s_ninode);
772: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
773: canino(*ip);
774: candaddr(fp->s_tfree);
775: canino(fp->s_tinode);
776:
777: /* Test for rationality. */
778: maxinode = (fp->s_isize - INODEI) * INOPB + 1;
779: if (fp->s_isize >= fp->s_fsize)
780: return 0;
781: if ((fp->s_tfree < fp->s_nfree)
782: || (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
783: return 0;
784: if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
785: return 0;
786: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
787: if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
788: return 0;
789: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
790: if ((*ip < 1) || (*ip > maxinode))
791: return 0;
792: if (fp->s_fsize > (daddr_t)size)
793: return 0;
794: if (fp->s_fsize > (daddr_t)size)
795: nonfatal("warning: filesystem size=%ld but partition size=%ld",
796: (long)fp->s_fsize, size);
797: return 1;
798: }
799:
800: /*
801: * Make new devices with /etc/mkdev if appropriate.
802: */
803: void
804: mkdev()
805: {
806: int hdc;
807:
808: cls(0);
809: printf("Most PC compatible computer systems use MFM, RLL, IDE, or ESDI disk\n");
810: printf("controllers and disk drives. A few percent use SCSI disk drives.\n");
811: printf("Please indicate the type(s) of disk drive(s) used in your computer system.\n");
812: printf("If you are uncertain of the type, please select choice 1.\n\n");
813: printf("Are you using:\n\n");
814: printf("1. AT-compatible hard drive controller (IDE/RLL/MFM/ESDI).\n");
815: printf("2. SCSI hard drive controller.\n");
816: printf("3. Both.\n\n");
817: hdc = get_int(1, 3, "Enter your choice:");
818:
819: /*
820: * Note: -b option to mkdev also OK for update
821: */
822: sprintf(cmd, "/etc/mkdev -b%s%s %s %s",
823: (dflag) ? "d" : "",
824: (vflag) ? "v" : "",
825: (hdc == 1 || hdc == 3) ? "at" : "",
826: (hdc == 2 || hdc == 3) ? "scsi" : "");
827: sys(cmd, S_NONFATAL);
828: add_devices();
829:
830: /* Call add_devices to read /tmp/devics for ALL types of drives. Previously,
831: * the 2 possible AT drives were hard coded so that they would always be read,
832: * even if only one or none were present.
833: * Bob H. (8/10/93)
834: */
835:
836: /* if (hdc == 2 || hdc == 3) */
837:
838: }
839:
840: /*
841: * Make filesystems on COHERENT partitions.
842: */
843: void
844: mkfs()
845: {
846: register int i;
847: char *name;
848:
849: cls(0);
850: printf(
851: "You must create an empty COHERENT filesystem on each COHERENT partition\n"
852: "before you can use it. Creating an empty filesystem will destroy all\n"
853: "previously existing data on the partition.\n"
854: );
855: for (i = 0; i < ndevices; i++) {
856: if (notflag(i, F_COH) || (isflag(i, F_ATDEV) && notflag(i, F_SCAN)))
857: continue;
858: printf("\n");
859: if (isflag(i, F_FS))
860: printf("Partition %d (%s) already contains a COHERENT filesystem.\n",
861: i, devname(i, 0));
862: if (i == root)
863: printf(
864: "\nWARNING!!!\n\n"
865: "The installation process expects a NEW file system in the root partition.\n"
866: "If you are trying to update an existing COHERENT partition, you must run\n"
867: "the COHERENT update. If you are trying to install again after a partial\n"
868: "or failed installation, a new root file system must be created again now.\n\n"
869: );
870: name = devname(i, 1);
871: again:
872: if (yes_no("Do you want to create a new COHERENT filesystem on partition %d", i)) {
873: if (notflag(i, F_ATDEV))
874: sprintf(cmd, "/etc/mkfs %s %lu", name, devices[i].d_size);
875: else if (notflag(i, F_PROTO)) {
876: printf("The attempt to scan %s for bad blocks previously failed.",
877: name);
878: if (yes_no("Do you want to create a new filesystem on it without a bad block list"))
879: sprintf(cmd, "/etc/mkfs %s %lu", name, devices[i].d_size);
880: else
881: continue;
882: } else
883: sprintf(cmd, "/etc/mkfs %s %s",
884: name, protoname(i));
885: clrflag(i, F_FS);
886: if (sys(cmd, S_NONFATAL) == 0) {
887: setflag(i, F_FS);
888: if (notflag(i, F_PROTO)) {
889: /* Stick a boot block on device. */
890: /* The proto does it in the other case. */
891: sprintf(cmd, "/bin/cp /conf/boot %s", name);
892: sys(cmd, S_NONFATAL);
893: }
894:
895: /*
896: * Mount the file system,
897: * create /lost+found,
898: * unmount it.
899: */
900: sprintf(cmd, "/etc/mount %s /mnt", name);
901: if (sys(cmd, S_NONFATAL))
902: continue;
903: sprintf(cmd, "/bin/mkdir /mnt/lost+found");
904: if (sys(cmd, S_NONFATAL) == 0)
905: sys(
906: "cd /mnt/lost+found \n"
907: "/bin/touch `/bin/from 1 to 200` \n"
908: "/bin/rm *",
909: S_IGNORE);
910: sprintf(cmd, "/etc/umount %s", name);
911: sys(cmd, S_NONFATAL);
912: } else if (i == root)
913: fatal("%s: root partition mkfs failed", name);
914: } else if (i == root) {
915: if (notflag(i, F_FS)) {
916: printf("You must create a filesystem on the root partition.\n");
917: goto again;
918: } else {
919: /* Stick a boot block on the root device. */
920: sprintf(cmd, "/bin/cp /conf/boot %s", name);
921: sys(cmd, S_NONFATAL);
922: }
923: }
924: }
925: }
926:
927: /*
928: * Place a bootstrap on the root filesystem.
929: * This is only called from update.
930: */
931: void
932: new_boot()
933: {
934: sprintf(cmd, "/bin/cp /conf/boot %s", devname(root, 1));
935: sys(cmd, S_FATAL);
936: }
937:
938: /*
939: * If PATCHFILE exists, execute it.
940: */
941: void
942: patches()
943: {
944: printf(
945: "\nThe kernel on your hard drive will now be patched to run on your system.\n");
946: if (access(PATCHFILE, F_OK) == 0) {
947: sprintf(cmd, "/bin/sh %s", PATCHFILE);
948: sys(cmd, S_NONFATAL);
949: }
950: }
951:
952: /*
953: * Generate a prototype name from a DEVICE entry name.
954: * Return a pointer to the statically allocated name.
955: */
956: char *
957: protoname(i) int i;
958: {
959: static char pname[5+NAMESIZE+6]; /* e.g. "/tmp/at0a.proto" */
960:
961: sprintf(pname, "/tmp/%s.proto", devices[i].d_dname);
962: return pname;
963: }
964:
965: /*
966: * Generate a raw device name from a DEVICE entry name.
967: * Return a pointer to the statically allocated name.
968: * If flag and not one of the built-in AT device names,
969: * the device is in /tmp/dev rather than /dev.
970: */
971: char *
972: rawname(i, flag) int i, flag;
973: {
974: static char rname[4+4+1+1+NAMESIZE]; /* e.g. "/tmp/dev/rat0a" */
975:
976: sprintf(rname, "/tmp/dev/r%s", devices[i].d_dname);
977: return (flag && notflag(i, F_ATDEV)) ? rname : rname+4;
978: }
979:
980: /*
981: * Patches to be done to the kernel - but can't do them yet because
982: * kernel hasn't been linked.
983: */
984: void
985: rootpatch()
986: {
987: char line[120];
988:
989: /*
990: * After fdisk() we know "root". Write to PATCHFILE the patches
991: * that will be needed when a new kernel is linked at /mnt/coherent.
992: */
993: /* For third kernel. */
994: sprintf(line, "unsigned long\t%s = 0x%lx;", BAR_BAR, atol(serialno));
995: cohtune_ent("cohmain", BAR_BAR, line);
996:
997: sprintf(line, "unsigned long\t%s = 0x%lx;", BAR_ENTRY, atol(serialno));
998: cohtune_ent("cohmain", BAR_ENTRY, line);
999:
1000: sprintf(line, "dev_t\t\t%s = makedev(%d,%d);",
1001: ROOTDEV, devices[root].d_major, devices[root].d_minor);
1002: cohtune_ent("cohmain", ROOTDEV, line);
1003:
1004: sprintf(line, "dev_t\t\t%s = makedev(%d,%d);",
1005: PIPEDEV, devices[root].d_major, devices[root].d_minor);
1006: cohtune_ent("cohmain", PIPEDEV, line);
1007:
1008: /* For the second kernel. */
1009: sprintf(cmd,
1010: "echo /conf/patch -v /mnt/coherent ronflag=0 "
1011: "\\\"%s\\=makedev\\(%d,%d\\)\\\" "
1012: "\\\"%s\\=makedev\\(%d,%d\\)\\\" >> %s\n",
1013: ROOTDEV, devices[root].d_major, devices[root].d_minor,
1014: PIPEDEV, devices[root].d_major, devices[root].d_minor, PATCHFILE);
1015: sys(cmd, S_FATAL);
1016: }
1017:
1018: /*
1019: * Need to mount root.
1020: * Need to set serialno.
1021: * Remove /usr/man/{ALL,COHERENT,MULTI}, /usr/man/man.tar*
1022: * Save off any special files before copying in the update
1023: * Need to umount root.
1024: */
1025: void
1026: save_files()
1027: {
1028: char buf[20]; /* more than enough for a serial # */
1029: int fd; /* file descriptor */
1030: int i;
1031: char *s;
1032:
1033: cls(1);
1034: printf("We will now mount your existing COHERENT root filesystem...\n");
1035: sprintf(cmd, "/etc/mount %s /mnt", devname(root, 1));
1036: sys(cmd, S_FATAL);
1037:
1038: if (!is_dir("/mnt/dev")) /* sanity check! */
1039: fatal("Corrupt or incorrect root filesystem specified");
1040: /*
1041: * Read in the old 286 serial number and save it off for later.
1042: * If it doesn't exist on the disk, make the user re-enter
1043: * the old serial number by hand.
1044: */
1045: serialno[0] = '\0';
1046: buf[0] = '\0';
1047: if ((fd = open("/mnt/etc/serialno", 0)) >= 0) {
1048: read(fd, buf, sizeof(buf)-1); /* ignore errors */
1049: close(fd);
1050: if (!isserial(buf)) /* sets serialno[] */
1051: serialno[0] = '\0';
1052: }
1053: if (serialno[0] == '\0') {
1054: printf(
1055: "\nA card included with your original COHERENT distribution gives the\n"
1056: "serial number of your copy of COHERENT.\n\n"
1057: );
1058: for (i = 1; i <= 3; i++) {
1059: s = get_line("Type in the serial number from the card:");
1060: if (isserial(s))
1061: break;
1062: if (i < 3)
1063: printf("Invalid serial number, please try again.\n");
1064: else
1065: fatal("invalid serial number");
1066: }
1067: }
1068:
1069: printf("\nRemoving old on-line COHERENT manual pages -- please wait...\n");
1070: sys("/bin/rm -rf /mnt/usr/man/ALL /mnt/usr/man/COHERENT "
1071: "/mnt/usr/man/MULTI /mnt/usr/man/man.tar*", S_NONFATAL);
1072: sync();
1073:
1074: /*
1075: * Save off any special files just in case the user wants to
1076: * get the old ones back...
1077: */
1078: if (!is_dir("/mnt/old_coh")) {
1079: printf(
1080: "\nSaving existing configuration files to directory /old_coh -- please wait...\n\n"
1081: );
1082: sys("mkdir -r `cat /conf/upd_dirs`", S_NONFATAL);
1083: sys(
1084: "for a in `cat /conf/upd_save` ;"
1085: " do ;"
1086: " cp -d /mnt/$a /mnt/old_coh/$a 2>/dev/null && echo $a... ;"
1087: " done ;"
1088: " echo", S_IGNORE);
1089: sync();
1090: } else
1091: printf("Directory /old_coh contains configuration file backups.\n");
1092:
1093:
1094: sprintf(cmd, "rm -f /mnt/coherent.* /mnt/drv/*"); /* rm stale copies */
1095: sys(cmd, S_FATAL);
1096:
1097: sprintf(cmd, "/etc/umount %s", devname(root, 1));
1098: sys(cmd, S_FATAL);
1099:
1100: }
1101:
1102: /*
1103: * Configure user devices.
1104: * Assumes hard disk filesystem mounted on /mnt.
1105: * Write lines to /etc/mount.all, /etc/umount.all to [u]mount the user devices.
1106: */
1107: void
1108: user_devices()
1109: {
1110: register int i, status;
1111: register char *s, *s2, *name, *rname;
1112:
1113: if (ncohdev == 1) {
1114: sys("/bin/echo /dev/root >>/mnt/etc/checklist", S_NONFATAL);
1115: return;
1116: }
1117:
1118: /* Create user device names. */
1119: cls(0);
1120: printf(
1121: "Your system includes %d partition%s in addition to the root partition.\n"
1122: "These partitions are usually mounted on directories in the COHERENT\n"
1123: "root filesystem when the system goes into multiuser mode.\n"
1124: "For example, one non-root partition might be mounted on\n"
1125: "directory \"/u\", another on \"/v\", and so on.\n"
1126: "You now may specify where you want each partition mounted.\n",
1127: ncohdev - 1, ncohdev == 2 ? "" : "s");
1128: for (i = 0; i < ndevices; i++) {
1129: if (notflag(i, F_COH) || notflag(i, F_FS) || isflag(i, F_ROOT))
1130: continue;
1131: name = devname(i, 0);
1132: rname = rawname(i, 0);
1133: printf("\nPartition %d (%s):\n", i, name);
1134: if (yes_no("Do you want %s mounted", name)) {
1135: setflag(i, F_MOUNT);
1136: again:
1137: s = get_line("Where do you want to mount it?");
1138: if (*s != '/') {
1139: printf("Type a directory name beginning with '/', such as \"/u\".\n");
1140: goto again;
1141: } else if ((s2 = strchr(s, ' ')) != NULL)
1142: *s2 = '\0';
1143: sprintf(cmd, "/mnt/%s", s);
1144: if ((status = is_dir(cmd)) == -1) {
1145: printf("%s exists but is not a directory.\n", s);
1146: goto again;
1147: } else if (status == 1) {
1148: strcpy(buf2, s);
1149: printf("Directory %s already exists.\n", s);
1150: if (!yes_no("Are you sure you want %s mounted on %s", name, s))
1151: goto again;
1152: s = buf;
1153: strcpy(s, buf2);
1154: } else {
1155: /* Make the target directory, uid=bin, gid=bin. */
1156: sprintf(cmd, "/bin/mkdir -r /mnt%s", s);
1157: if (sys(cmd, S_NONFATAL))
1158: goto again;
1159: sprintf(cmd, "/bin/chown bin /mnt%s", s);
1160: sys(cmd, S_NONFATAL);
1161: sprintf(cmd, "/bin/chgrp bin /mnt%s", s);
1162: sys(cmd, S_NONFATAL);
1163: }
1164: printf("%s will be mounted on %s when COHERENT goes multiuser.\n",
1165: name, s);
1166:
1167: /* Change e.g. /usr/src to usr_src. */
1168: strcpy(buf2, &s[1]);
1169: while ((s2 = strchr(buf2, '/')) != NULL)
1170: *s2 = '_';
1171:
1172: /* Make link to pseudo-device, e.g. "/dev/usr_src". */
1173: sprintf(cmd, "/mnt/dev/%s", buf2);
1174: if (exists(cmd))
1175: status = 1; /* use normal name */
1176: else {
1177: sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/%s",
1178: name, buf2);
1179: if ((status = sys(cmd, S_NONFATAL)) == 0)
1180: printf(
1181: "/dev/%s is linked to %s to provide a mnemonic device name.\n",
1182: buf2, name);
1183: }
1184:
1185: /* Add lines to /etc/mount.all, /etc/umount.all. */
1186: if (status == 0)
1187: sprintf(cmd, "/bin/echo /etc/mount /dev/%s %s >>/mnt/etc/mount.all",
1188: buf2, s);
1189: else
1190: sprintf(cmd, "/bin/echo /etc/mount %s %s >>/mnt/etc/mount.all",
1191: name, s);
1192: sys(cmd, S_NONFATAL);
1193: if (status == 0)
1194: sprintf(cmd, "/bin/echo /etc/umount /dev/%s >>/mnt/etc/umount.all",
1195: buf2);
1196: else
1197: sprintf(cmd, "/bin/echo /etc/umount %s >>/mnt/etc/umount.all",
1198: name);
1199: sys(cmd, S_NONFATAL);
1200:
1201: /* And again, for the raw device. */
1202: sprintf(cmd, "/mnt/dev/r%s", buf2);
1203: if (exists(cmd))
1204: status = 1;
1205: else {
1206: sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/r%s",
1207: rname, buf2);
1208: if ((status = sys(cmd, S_NONFATAL)) == 0)
1209: printf(
1210: "/dev/r%s is linked to %s to provide a mnemonic device name.\n",
1211: buf2, rname);
1212: }
1213:
1214: /* Add raw device line to /etc/checklist. */
1215: if (status == 0)
1216: sprintf(cmd, "/bin/echo /dev/r%s >>/mnt/etc/checklist",
1217: buf2);
1218: else
1219: sprintf(cmd, "/bin/echo %s >>/mnt/etc/checklist",
1220: rname);
1221: sys(cmd, S_NONFATAL);
1222: } else {
1223: /* Not mounted, check using standard name. */
1224: sprintf(cmd, "/bin/echo %s >>/mnt/etc/checklist", rname);
1225: sys(cmd, S_NONFATAL);
1226: }
1227: }
1228: sys("/bin/echo /dev/root >>/mnt/etc/checklist", S_NONFATAL);
1229:
1230: /* Link /dev/dos if desired. */
1231: if (yes_no("Do you use both COHERENT and MS-DOS on your hard disk")) {
1232: i = get_int(0, ndevices-1, "Enter the partition number of your MS-DOS partition:");
1233: sprintf(cmd, "/bin/ln -f /mnt%s /mnt/dev/dos", devname(i, 0));
1234: if (sys(cmd, S_NONFATAL) == 0)
1235: printf(
1236: "Device name /dev/dos is now linked to %s for use as a mnemonic\n"
1237: "device name. You may use the \"dos*\" family of commands to transfer files\n"
1238: "to and from the MS-DOS partition on your hard disk as well as MS-DOS floppies.\n",
1239: devname(i, 0));
1240: printf("\n");
1241: }
1242: }
1243:
1244:
1245:
1246: /*
1247: * Hi there.
1248: */
1249: void
1250: welcome()
1251: {
1252: register char *s;
1253: int i;
1254:
1255: cls(0);
1256: printf(
1257: "\n\n\n\n\n\n\n\n"
1258: " The COHERENT System\n\n"
1259: " Copyright (c) 1982, 1992 by Mark Williams Company\n\n"
1260: " 60 Revere Drive, Northbrook, IL 60062\n\n"
1261: " 708-291-6700, 708-291-6750 (FAX)\n"
1262: "\n\n\n\n\n\n"
1263: );
1264:
1265: cls(1);
1266: printf(
1267: "Welcome to the COHERENT operating system!\n\n"
1268: "Your computer is now running COHERENT "
1269: "386"
1270: " from the floppy disk.\n");
1271: if (update)
1272: printf(
1273: "This program will update your existing COHERENT 4.0.x system to COHERENT 4.2.0.\n"
1274: "\n"
1275: "Be sure to read the section on \"Updating\" in the COHERENT 386 Release\n"
1276: "Notes prior to attempting this update!\n\n"
1277: "Please be patient and read the instructions on the screen carefully.\n"
1278: "\n"
1279: );
1280: else
1281: printf(
1282: "This program will install COHERENT onto your hard disk.\n"
1283: "\n"
1284: "If you are already running COHERENT on your hard disk, you must perform an\n"
1285: "update rather than a full installation. To do so, please REBOOT NOW and\n"
1286: "follow the detailed update instructions in the COHERENT release notes supplied\n"
1287: "with this release.\n"
1288: "\n"
1289: "You can interrupt installation at any time by typing <Ctrl-C>;\n"
1290: "then reboot and start the installation procedure again.\n"
1291: "Please be patient and read the instructions on the screen carefully.\n"
1292: "\n"
1293: );
1294: cls(1);
1295: if (update)
1296: sys("/etc/kbdinstall -u", S_NONFATAL);
1297: else
1298: sys("/etc/kbdinstall -b", S_NONFATAL);
1299:
1300: cls(1);
1301: if (!update) {
1302: printf(
1303: "A card included with your distribution gives the serial number\n"
1304: "of your copy of COHERENT.\n"
1305: );
1306: for (i = 1; i <= 3; i++) {
1307: s = get_line("Type in the serial number from the card:");
1308: if (isserial(s))
1309: return;
1310: printf("Invalid serial number, please try again.\n");
1311: }
1312: fatal("invalid serial number");
1313: }
1314: }
1315:
1316: /*
1317: * Generate a partition table device name from a DEVICE entry name.
1318: * Return a pointer to the statically allocated name.
1319: * If flag and not one of the built-in AT device names,
1320: * the device is in /tmp/dev rather than /dev.
1321: */
1322: char *
1323: xname(i, flag) int i, flag;
1324: {
1325: static char xname[4+4+1+NAMESIZE]; /* e.g. "/tmp/dev/at0x" */
1326:
1327: #if 0
1328: sprintf(xname, "/tmp/dev/%s", devices[i].d_xname);
1329: return (flag && notflag(i, F_ATDEV)) ? xname : xname+4;
1330: #endif
1331:
1332: sprintf(xname, "/dev/%s", devices[i].d_xname);
1333: return (xname);
1334: }
1335:
1336: /* end of build.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.