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