/* Stopgap, until Paul does the right thing */ #define ESC 27 #define TAB 9 #include #include #define DKTYPENAMES #include #include #include #include #include #include #include #include #include "sysinstall.h" int sectstoMb(int, int); char *partname[MAXPARTITIONS] = {"a", "b", "c", "d", "e", "f", "g", "h"}; #define EDITABLES 3 #define FSTYPE 0 #define UPARTSIZES 1 #define MOUNTPOINTS 2 struct field { int y; int x; int width; char field[80]; } field; struct field label_fields[MAXPARTITIONS][EDITABLES]; void setup_label_fields(struct disklabel *lbl) { int i; for (i=0; i < MAXPARTITIONS; i++) { label_fields[i][0].y = 4 + (i * 2); label_fields[i][0].x = 15; label_fields[i][0].width = 15; sprintf(label_fields[i][0].field, "%s", fstypenames[lbl->d_partitions[i].p_fstype]); label_fields[i][1].y = 4 + (i * 2); label_fields[i][1].x = 35; label_fields[i][1].width = 9; sprintf(label_fields[i][1].field, "%d", sectstoMb(lbl->d_partitions[i].p_size, lbl->d_secsize)); label_fields[i][2].y = 4 + (i * 2); label_fields[i][2].x = 45; label_fields[i][2].width = 30; } sprintf(label_fields[0][2].field, "%s", "/"); sprintf(label_fields[1][2].field, "%s", "swap"); sprintf(label_fields[4][2].field, "%s", "/usr"); } void update_label_form(WINDOW *window, struct disklabel *lbl) { int i; long used = 0,ul; mvwprintw(window, 2, 2, "Partition"); mvwprintw(window, 2, 15, "Filesystem Type"); mvwprintw(window, 2, 35, "Size"); mvwprintw(window, 2, 45, "Mount point"); for (i=0; i < MAXPARTITIONS; i++) { mvwprintw(window, 4+(i*2), 6, "%s", partname[i]); mvwprintw(window, label_fields[i][0].y, label_fields[i][0].x, "%s", &label_fields[i][0].field); if(i < 2 || i > 3) { ul = strtol(label_fields[i][1].field,0,0); sprintf(label_fields[i][1].field, "%lu",ul); used += ul; } mvwprintw(window, label_fields[i][1].y, label_fields[i][1].x, "%-5s", &label_fields[i][1].field); if (label_fields[i][2].field) mvwprintw(window, label_fields[i][2].y, label_fields[i][2].x, "%s", &label_fields[i][2].field); } mvwprintw(window, 20, 10, "Allocated %5luMb, Unalloacted %5lu Mb", used, disk_size(lbl) - used); wrefresh(window); } int disk_size(struct disklabel *lbl) { int size; size = lbl->d_secsize * lbl->d_nsectors * lbl->d_ntracks * lbl->d_ncylinders; return (size / 1024 / 1024); } int sectstoMb(int nsects, int secsize) { int size; size = nsects * secsize; if (size) size /= 1024 * 1024; return (size); } int Mbtosects(int Mb, int secsize) { int nsects; nsects = (Mb * 1024 * 1024) / secsize; return(nsects); } int rndtocylbdry(int size, int secpercyl) { int nocyls; nocyls = size / secpercyl; if ((nocyls * secpercyl) < size) nocyls++; return (nocyls * secpercyl); } void default_disklabel(struct disklabel *lbl, int avail_sects, int offset) { int nsects; /* Fill in default label entries */ lbl->d_magic = DISKMAGIC; bcopy("INSTALLATION", lbl->d_typename, strlen("INSTALLATION")); lbl->d_rpm = 3600; lbl->d_interleave = 1; lbl->d_trackskew = 0; lbl->d_cylskew = 0; lbl->d_magic2 = DISKMAGIC; lbl->d_checksum = 0; lbl->d_bbsize = BBSIZE; lbl->d_sbsize = SBSIZE; lbl->d_npartitions = 5; /* Set up c and d as raw partitions for now */ lbl->d_partitions[2].p_size = avail_sects; lbl->d_partitions[2].p_offset = offset; lbl->d_partitions[2].p_fsize = DEFFSIZE; /* XXX */ lbl->d_partitions[2].p_fstype = FS_UNUSED; lbl->d_partitions[2].p_frag = DEFFRAG; lbl->d_partitions[3].p_size = lbl->d_secperunit; lbl->d_partitions[3].p_offset = 0; lbl->d_partitions[3].p_fsize = DEFFSIZE; lbl->d_partitions[3].p_fstype = FS_UNUSED; lbl->d_partitions[3].p_frag = DEFFRAG; /* Default root */ nsects = rndtocylbdry(Mbtosects(DEFROOTSIZE, lbl->d_secsize), lbl->d_secpercyl); offset = rndtocylbdry(offset, lbl->d_secpercyl); lbl->d_partitions[0].p_size = nsects; lbl->d_partitions[0].p_offset = offset; lbl->d_partitions[0].p_fsize = DEFFSIZE; lbl->d_partitions[0].p_fstype = FS_BSDFFS; lbl->d_partitions[0].p_frag = DEFFRAG; avail_sects -= nsects; offset += nsects; nsects = rndtocylbdry(Mbtosects(DEFSWAPSIZE, lbl->d_secsize), lbl->d_secpercyl); lbl->d_partitions[1].p_size = nsects; lbl->d_partitions[1].p_offset = offset; lbl->d_partitions[1].p_fsize = DEFFSIZE; lbl->d_partitions[1].p_fstype = FS_SWAP; lbl->d_partitions[1].p_frag = DEFFRAG; avail_sects -= nsects; offset += nsects; nsects = rndtocylbdry(Mbtosects(DEFUSRSIZE, lbl->d_secsize), lbl->d_secpercyl); if (avail_sects > nsects) nsects = avail_sects; lbl->d_partitions[4].p_size = nsects; lbl->d_partitions[4].p_offset = offset; lbl->d_partitions[4].p_fsize = DEFFSIZE; lbl->d_partitions[4].p_fstype = FS_BSDFFS; lbl->d_partitions[4].p_frag = DEFFRAG; } void edit_disklabel(struct disklabel *lbl) { int key=0; int x_pos = 0; int y_pos = 0; WINDOW *window; if (use_shadow) draw_shadow(stdscr, 1, 1, LINES-3, COLS-5); window = newwin(LINES - 2, COLS - 4, 0, 0); keypad(window, TRUE); draw_box(window, 1, 1, LINES - 3, COLS - 5, dialog_attr, border_attr); wattrset(window, dialog_attr); setup_label_fields(lbl); do { update_label_form(window, lbl); key = edit_line(window, label_fields[y_pos][x_pos].y, label_fields[y_pos][x_pos].x, label_fields[y_pos][x_pos].field, label_fields[y_pos][x_pos].width, 20); switch(key) { case KEY_UP: if (y_pos != 0) y_pos--; break; case KEY_DOWN: if (++y_pos == MAXPARTITIONS) y_pos--; break; case '\n': case TAB: x_pos++; if (x_pos == EDITABLES) { x_pos = 0; if (++y_pos == MAXPARTITIONS) y_pos--; } break; case KEY_BTAB: x_pos--; if (x_pos < 0) { x_pos = EDITABLES - 1; if (--y_pos < 0) y_pos++; } break; default: break; } } while (key != '\033'); dialog_clear(); } int build_disklabel(struct disklabel *lbl) { int i, offset; int nsects; int total_sects; /* Get start of FreeBSD partition from default label */ offset = lbl->d_partitions[2].p_offset; for (i=0; i < MAXPARTITIONS; i++) { if (strlen(label_fields[i][MOUNTPOINTS].field) && atoi(label_fields[i][UPARTSIZES].field)) { sprintf(scratch, "%s%s", avail_disknames[inst_disk], partname[i]); Fname[Nfs] = StrAlloc(scratch); Fmount[Nfs] = StrAlloc(label_fields[i][MOUNTPOINTS].field); Nfs++; nsects = Mbtosects(atoi(label_fields[i][UPARTSIZES].field), lbl->d_secsize); lbl->d_partitions[i].p_size = nsects; lbl->d_partitions[i].p_offset = offset; offset += nsects; total_sects += nsects; lbl->d_partitions[i].p_fstype = getfstype(label_fields[i][FSTYPE].field); lbl->d_npartitions = i+1; } else if (i < 2 || i > 3) { lbl->d_partitions[i].p_size = 0; lbl->d_partitions[i].p_offset = 0; lbl->d_partitions[i].p_fstype = 0; } Debug("Part%d: %d sects, %d offset, %d end, %d type", i, lbl->d_partitions[i].p_size, lbl->d_partitions[i].p_offset, lbl->d_partitions[i].p_size+ lbl->d_partitions[i].p_offset, lbl->d_partitions[i].p_fstype); } return 0; } int getfstype(char *fstype) { int i; for (i=0; i < FSMAXTYPES; i++) if (!strcasecmp(fstype, fstypenames[i])) return(i); return(FS_OTHER); } void display_disklabel(int disk) { int i, key=0; WINDOW *window; if (use_shadow) draw_shadow(stdscr, 1, 1, LINES-2, COLS-2); window = newwin(LINES-2, COLS-2, 1, 1); keypad(window, TRUE); draw_box(window, 1, 1, LINES - 2, COLS - 2, dialog_attr, border_attr); wattrset(window, dialog_attr); mvwprintw(window, 2, 2, "Dumping label for disk %d, %s\n", disk, avail_disklabels[disk].d_typename); mvwprintw(window, 3, 2, "magic = %lu",avail_disklabels[disk].d_magic); mvwprintw(window, 3, 22, "type = %x",avail_disklabels[disk].d_type); mvwprintw(window, 3, 32, "subtype = %x\n",avail_disklabels[disk].d_subtype); mvwprintw(window, 4, 2, "Typename = %s",avail_disklabels[disk].d_typename); mvwprintw(window, 4, 38, "Packname = %s",avail_disklabels[disk].d_packname); mvwprintw(window, 5, 74, "boot0 = %s",avail_disklabels[disk].d_boot0); mvwprintw(window, 5, 50, "boot1 = %s\n",avail_disklabels[disk].d_boot1); mvwprintw(window, 5, 2, "secsize = %ld",avail_disklabels[disk].d_secsize); mvwprintw(window, 5, 20, "nsectors = %ld",avail_disklabels[disk].d_nsectors); mvwprintw(window, 5, 30, "ntracks = %ld",avail_disklabels[disk].d_ntracks); mvwprintw(window, 5, 50, "ncylinders = %ld\n",avail_disklabels[disk].d_ncylinders); mvwprintw(window, 6, 2, "secpercyl = %ld",avail_disklabels[disk].d_secpercyl); mvwprintw(window, 6, 40, "secperunit = %ld\n",avail_disklabels[disk].d_secperunit); mvwprintw(window, 7, 2, "sparespertrack = %d",avail_disklabels[disk].d_sparespertrack); mvwprintw(window, 7, 20, "sparespercyl = %d",avail_disklabels[disk].d_sparespercyl); mvwprintw(window, 7, 40, "acylinders = %ld\n",avail_disklabels[disk].d_acylinders); mvwprintw(window, 8, 2, "rpm = %d",avail_disklabels[disk].d_rpm); mvwprintw(window, 8, 20, "interleave = %d",avail_disklabels[disk].d_interleave); mvwprintw(window, 8, 40, "trackskew = %d",avail_disklabels[disk].d_trackskew); mvwprintw(window, 8, 60, "cylskew = %d\n",avail_disklabels[disk].d_cylskew); mvwprintw(window, 9, 2, "headswitch = %ld",avail_disklabels[disk].d_headswitch); mvwprintw(window, 9, 30, "trkseek = %ld",avail_disklabels[disk].d_trkseek); mvwprintw(window, 9, 55, "flags = %ld\n",avail_disklabels[disk].d_flags); mvwprintw(window, 10, 2, "Drivedata"); for(i=0; i< NDDATA; i++) { mvwprintw(window, 10, 11 + (i*10), " : %d = %ld",i,avail_disklabels[disk].d_drivedata[i]); } mvwprintw(window, 11, 2, "Spare"); for (i=0; i< NSPARE; i++) { mvwprintw(window, 11, 7 + (i*10), " : %d = %ld",i,avail_disklabels[disk].d_spare[i]); } mvwprintw(window, 12, 2, "magic2 = %lu",avail_disklabels[disk].d_magic2); mvwprintw(window, 12, 40, "checksum = %d\n",avail_disklabels[disk].d_checksum); mvwprintw(window, 13, 2, "npartitions = %d",avail_disklabels[disk].d_npartitions); mvwprintw(window, 13, 25, "bbsize = %lu",avail_disklabels[disk].d_bbsize); mvwprintw(window, 13, 50, "sbsize = %lu\n",avail_disklabels[disk].d_sbsize); for (i=0; i< MAXPARTITIONS; i++) { mvwprintw(window, 14+i, 2, "%d: size: %ld",i,avail_disklabels[disk].d_partitions[i].p_size); mvwprintw(window, 14+i, 20, "offset: %ld",avail_disklabels[disk].d_partitions[i].p_offset); mvwprintw(window, 14+i, 36, "fsize: %ld",avail_disklabels[disk].d_partitions[i].p_fsize); mvwprintw(window, 14+i, 49, "fstype: %d",avail_disklabels[disk].d_partitions[i].p_fstype); mvwprintw(window, 14+i, 60, "frag: %d",avail_disklabels[disk].d_partitions[i].p_frag); mvwprintw(window, 14+i, 70, "cpg: %d",avail_disklabels[disk].d_partitions[i].p_cpg); } dialog_update(); while (key != '\n' && key != ' ' && key != '\033') key = wgetch(window); delwin(window); dialog_clear(); } static int AskWhichPartition(char *prompt) { char buf[10]; int i; *buf = 0; i = AskEm(stdscr,prompt,buf,1); if(i != '\n' && i != '\r') return -1; if(!strchr("abefghABEFGH",*buf)) return -1; return tolower(*buf) - 'a'; } static void CleanMount(int disk, int part) { int i = MP[disk][part]; if(Fmount[i]) { free(Fmount[i]); Fmount[i] = 0; } if(Fname[i]) { free(Fname[i]); Fname[i] = 0; } if(Ftype[i]) { free(Ftype[i]); Ftype[i] = 0; } MP[disk][part] = 0; } void DiskLabel() { int i,j,done=0,diskno,flag,k; char buf[128]; struct disklabel *lbl,olbl; u_long cyl,hd,sec,tsec; u_long l1,l2,l3,l4; *buf = 0; i = AskEm(stdscr,"Enter number of disk to Disklabel ",buf,1); printf("%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; while(!done) { clear(); standend(); j = 0; mvprintw(j++,0,"%s -- Diskspace editor -- DISKLABEL",TITLE); j++; mvprintw(j++,0,"Part Start End Blocks MB Type Mountpoint"); for(i=0;i=lbl->d_npartitions) continue; 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("%-10s ",fstypenames[k]); if(i == OURPART) printw(""); else if(i == RAWPART) printw(""); else if(Fmount[MP[diskno][i]]) printw(Fmount[MP[diskno][i]]); } mvprintw(21,0,"Commands available:"); mvprintw(22,0,"(S)ize (M)ountpoint (D)elete (R)eread (W)rite (Q)uit"); mvprintw(23,0,"Enter Command> "); i=getch(); switch(i) { case 'd': case 'D': j = AskWhichPartition("Delete which partition ? "); if(j < 0) 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 's': case 'S': j = AskWhichPartition("Change size of which partition ? "); if(j < 0) 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) break; if(lbl->d_partitions[OURPART].p_size == 0) break; l1=lbl->d_partitions[OURPART].p_offset; l2=lbl->d_partitions[OURPART].p_offset + lbl->d_partitions[OURPART].p_size; for (i=0;id_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)) break; sprintf(buf,"%lu",(l2-l1+1024L)/2048L); i = AskEm(stdscr,"Size of slice in MB ",buf,10); l3=strtol(buf,0,0) * 2048L; if(!l3) 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;id_partitions[j].p_fstype; if(k != FS_BSDFFS && k != FS_MSDOS && k != FS_SWAP) break; if(!lbl->d_partitions[j].p_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,"Mount on directory ",buf,28); if(i != '\n' && i != '\r') break; } CleanMount(diskno,j); for(k=1;k= MAX_NO_FS) break; Fmount[k] = StrAlloc(buf); MP[diskno][j] = k; sprintf(buf,"%s%c",Dname[diskno],j+'a'); Fname[MP[diskno][j]] = StrAlloc(buf); if(lbl->d_partitions[j].p_fstype == FS_BSDFFS) Ftype[MP[diskno][j]] = StrAlloc("ufs"); else if(lbl->d_partitions[j].p_fstype == FS_MSDOS) Ftype[MP[diskno][j]] = StrAlloc("msdos"); else if(lbl->d_partitions[j].p_fstype == FS_SWAP) Ftype[MP[diskno][j]] = StrAlloc("swap"); Fsize[MP[diskno][j]] = (lbl->d_partitions[j].p_size+1024)/2048; 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]; flag=1; if (ioctl(Dfd[diskno], DIOCWLABEL, &flag) < 0) Fatal("Couldn't enable writing of labels"); 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)); flag=0; if (ioctl(Dfd[diskno], DIOCWLABEL, &flag) < 0) Fatal("Couldn't disable writing of labels"); break; case 'q': case 'Q': if(!memcmp(lbl,Dlbl[diskno],sizeof *lbl)) return; /* XXX be more selective here */ for(i=0;i