/* * $Id: label.c,v 1.31 1994/12/27 23:26:51 jkh Exp $ */ #include #include #define DKTYPENAMES #include #include #include #include #include #include #include #include #include "sysinstall.h" static int AskWhichPartition(char *prompt) { char buf[10]; int i; *buf = 0; i = AskEm(stdscr, prompt, buf, 2); if (i != '\n' && i != '\r') return -1; if (!strchr("abefghABEFGH",*buf)) return -1; return tolower(*buf) - 'a'; } void DiskLabel() { int i, j, done = 0, diskno, k; char buf[128],*p; struct disklabel *lbl, olbl; struct dos_partition dp[NDOSPART]; u_long cyl, hd, sec, tsec; u_long l1, l2, l3, l4; char *yip = NULL; u_long allocated_space, ourpart_size, ourpart_offset; *buf = 0; i = AskEm(stdscr, "Enter number of disk to Disklabel> ", buf, 3); Debug("%d", i); if (i != '\n' && i != '\r') return; diskno = atoi(buf); if (!(diskno >= 0 && diskno < MAX_NO_DISKS && Dname[diskno])) { return; } olbl = *Dlbl[diskno]; lbl = &olbl; cyl = lbl->d_ncylinders; hd = lbl->d_ntracks; sec = lbl->d_nsectors; tsec = lbl->d_secperunit; for (i = lbl->d_npartitions; i < MAXPARTITIONS; i++) { lbl->d_partitions[i].p_offset = 0; lbl->d_partitions[i].p_size = 0; lbl->d_partitions[i].p_fstype = 0; } lbl->d_npartitions = MAXPARTITIONS; if(Dname[diskno][0] == 's' && Dname[diskno][1] == 'd') lbl->d_type = DTYPE_SCSI; else lbl->d_type = DTYPE_ST506; while(!done) { clear(); standend(); if (yip) { standout(); mvprintw(24, 0, yip); standend(); beep(); yip = NULL; } j = 0; mvprintw(j++, 0, "%s -- Diskspace editor -- DISKLABEL", TITLE); j++; allocated_space = 0; ourpart_size = lbl->d_partitions[OURPART].p_size; ourpart_offset = lbl->d_partitions[OURPART].p_offset; mvprintw(j++, 0, "Part Start End Blocks MB Type Action Mountpoint"); for (i = 0; i < MAXPARTITIONS; i++) { refresh(); mvprintw(j++, 0, "%c ", 'a'+i); printw(" %8u %8u %8u %5u ", lbl->d_partitions[i].p_offset, lbl->d_partitions[i].p_offset+ (lbl->d_partitions[i].p_size ? lbl->d_partitions[i].p_size-1 : 0), lbl->d_partitions[i].p_size, (lbl->d_partitions[i].p_size + 1024)/2048); k = lbl->d_partitions[i].p_fstype; if (k > FSMAXTYPES) printw("%04x ", k); else printw("%-7.7s ", fstypenames[k]); if(!MP[diskno][i]) printw(" "); else if(!strcmp(Ftype[MP[diskno][i]],"swap")) printw("swap "); else if(Faction[MP[diskno][i]]) printw("newfs "); else printw("mount "); if (i == OURPART) printw(""); else if (i == RAWPART) printw(""); else { if (Fmount[MP[diskno][i]]) printw(Fmount[MP[diskno][i]]); if ((lbl->d_partitions[i].p_offset >= ourpart_offset) && ((lbl->d_partitions[i].p_offset + lbl->d_partitions[i].p_size) <= (ourpart_offset + ourpart_size))) allocated_space += lbl->d_partitions[i].p_size; } } mvprintw(17, 0, "Total size: %8lu blocks %5luMb", ourpart_size, (ourpart_size + 1024)/2048); mvprintw(18, 0, "Space allocated: %8lu blocks %5luMb", allocated_space, (allocated_space + 1024)/2048); mvprintw(20, 0, "Commands available: "); if (memcmp(lbl, Dlbl[diskno], sizeof *lbl)) { standout(); printw("Use (W)rite to save changes to disk"); standend(); } mvprintw(21, 0, "(H)elp (T)utorial (E)dit (A)ssign (D)elete (R)eread (W)rite (Q)uit"); mvprintw(22, 0, "(P)reserve (S)lice"); mvprintw(23, 0, "Enter Command> "); i=getch(); switch(i) { case 'h': case 'H': case '?': clear(); mvprintw(0, 0, "%s -- Diskspace editor -- DISKLABEL -- Command Help Basic commands: (H)elp - This screen (T)utorial - More detailed information on MBRs, disklabels, etc. (E)dit - Edit an existing disklabel entry (A)ssign - Assign a filesystem (or swap) to a partition (D)elete - Delete an existing disklabel entry (R)eread - Re-read disklabel from disk, discarding any changes (W)rite - Write updated disklabel information to disk (P)reserve - Don't newfs the filesystem (preserve old contents) (S)lice - Import foreign slice from MBR (for example, DOS) (Q)uit - Exit from the disklabel editor Press any key to return to Disklabel editor... ", TITLE); getch(); break; case 't': case 'T': ShowFile(HELPME_FILE,"Help file for disklayout"); break; case 'd': case 'D': j = AskWhichPartition("Delete which partition> "); if (j < 0) { yip = "Invalid partition"; break; } CleanMount(diskno, j); lbl->d_partitions[j].p_fstype = FS_UNUSED; lbl->d_partitions[j].p_size = 0; lbl->d_partitions[j].p_offset = 0; break; case 'p': case 'P': j = AskWhichPartition("Preserve which partition> "); if (j < 0) { yip = "Invalid partition"; break; } if (!MP[diskno][j]) { yip = "Unmounted partitions are preserved by default"; break; } if (lbl->d_partitions[j].p_fstype == FS_SWAP) { yip = "swap partitions cannot be preserved."; break; } if (lbl->d_partitions[j].p_fstype != FS_BSDFFS) { yip = "All non-ufs partitions are preserved by default."; break; } if (!fixit && !strcmp(Fmount[MP[diskno][j]],"/")) { yip = "/ cannot be preserved."; break; } if (!fixit && !strcmp(Fmount[MP[diskno][j]],"/usr")) { yip = "/usr cannot be preserved."; break; } if (!fixit && !strcmp(Fmount[MP[diskno][j]],"/var")) { yip = "/var cannot be preserved."; break; } Faction[MP[diskno][j]] = 1 - Faction[MP[diskno][j]]; break; case 's': case 'S': read_dospart(Dfd[diskno],&dp[0]); *buf = 0; j = AskEm(stdscr,"Import which fdisk slice> ",buf,4); if(j != '\n' && j != '\r') break; i = strtoul(buf,0,0); if (i < 1 || i > 4) { yip = "Invalid slice, must be '1' to '4'"; break; } if (!dp[i-1].dp_size) { yip = "empty slice cannot be imported"; break; } j = AskWhichPartition("Import on which partition> "); if (j < 0) { yip = "Invalid partition"; break; } CleanMount(diskno, j); lbl->d_partitions[j].p_offset = dp[i-1].dp_start; lbl->d_partitions[j].p_size = dp[i-1].dp_size; switch (dp[i-1].dp_typ) { case 0x01: case 0x04: case 0x06: lbl->d_partitions[j].p_fstype=FS_MSDOS; break; default: lbl->d_partitions[j].p_fstype=FS_OTHER; break; } break; case 'e': case 'E': j = AskWhichPartition("Change size of which partition> "); if (j < 0) { yip = "Invalid partition"; break; } if (lbl->d_partitions[j].p_fstype != FS_BSDFFS && lbl->d_partitions[j].p_fstype != FS_UNUSED && lbl->d_partitions[j].p_fstype != FS_SWAP) { yip = "Invalid partition type"; break; } if (lbl->d_partitions[OURPART].p_size == 0) { yip = "No FreeBSD partition defined?"; break; } l1=lbl->d_partitions[OURPART].p_offset; l2=lbl->d_partitions[OURPART].p_offset + lbl->d_partitions[OURPART].p_size; for (i = 0; i < MAXPARTITIONS; i++) { if (i == OURPART) continue; if (i == RAWPART) continue; if (i == j) continue; if (lbl->d_partitions[i].p_size == 0) continue; if (lbl->d_partitions[i].p_offset >= l2) continue; if ((lbl->d_partitions[i].p_offset+ lbl->d_partitions[i].p_size) <= l1) continue; l3 = lbl->d_partitions[i].p_offset - l1; l4 = l2 - (lbl->d_partitions[i].p_offset+ lbl->d_partitions[i].p_size); if (l3 > 0 && l3 >= l4) l2 = l1+l3; else if (l4 > 0 && l4 > l3) l1 = l2-l4; else l2 = l1; } if (!(l2 - l1)) { yip = "Sizes unchanged - couldn't find room"; break; } sprintf(buf, "%lu", (l2-l1+1024L)/2048L); i = AskEm(stdscr, "Size of partition in MB> ", buf, 10); l3= strtol(buf, 0, 0) * 2048L; if (!l3) { yip = "Invalid size given"; break; } if (l3 > l2 - l1) l3 = l2 - l1; lbl->d_partitions[j].p_size = l3; lbl->d_partitions[j].p_offset = l1; if (j == 1) lbl->d_partitions[j].p_fstype = FS_SWAP; else lbl->d_partitions[j].p_fstype = FS_BSDFFS; break; case 'r': case 'R': olbl = *Dlbl[diskno]; /* XXX be more selective here */ for (i = 0; i < MAXPARTITIONS; i++) CleanMount(diskno, i); break; case 'a': case 'A': j = AskWhichPartition("Assign which partition> "); if (j < 0) { yip = "Invalid partition"; break; } k = lbl->d_partitions[j].p_fstype; if (k != FS_BSDFFS && k != FS_MSDOS && k != FS_SWAP) { yip = "Invalid partition type"; break; } if (!lbl->d_partitions[j].p_size) { yip = "Zero partition size"; break; } if (k == FS_SWAP) strcpy(buf, "swap"); else if (Fmount[MP[diskno][j]]) strcpy(buf, Fmount[MP[diskno][j]]); else *buf = 0; if (k != FS_SWAP) { i = AskEm(stdscr, "Directory mountpoint> ", buf, 28); if (i != '\n' && i != '\r') break; p = buf + strlen(buf) - 1; while (isspace(*p) && p >= buf) *p-- = '\0'; if (*buf && *buf != '/') { yip = "Mountpoint must start with a '/'"; break; } } CleanMount(diskno, j); if (!*buf) break; p = SetMount(diskno,j,buf); yip = p; break; case 'w': case 'W': *Dlbl[diskno] = *lbl; Dlbl[diskno]->d_magic = DISKMAGIC; Dlbl[diskno]->d_magic2 = DISKMAGIC; Dlbl[diskno]->d_checksum = 0; Dlbl[diskno]->d_checksum = dkcksum(Dlbl[diskno]); *lbl = *Dlbl[diskno]; enable_label(Dfd[diskno]); if (ioctl(Dfd[diskno], DIOCSDINFO, Dlbl[diskno]) == -1) Fatal("Couldn't set label: %s", strerror(errno)); if (ioctl(Dfd[diskno], DIOCWDINFO, Dlbl[diskno]) == -1) Fatal("Couldn't write label: %s", strerror(errno)); disable_label(Dfd[diskno]); yip = "Label written successfully."; break; case 'q': case 'Q': if (!memcmp(lbl, Dlbl[diskno], sizeof *lbl)) return; /* XXX be more selective here */ for (i = 0; i < MAXPARTITIONS; i++) CleanMount(diskno, i); return; break; } } }