1*b288bf5cSmartin /* $NetBSD: label.c,v 1.4 2018/11/20 19:02:07 martin Exp $ */ 226165e63Sdholland 326165e63Sdholland /* 426165e63Sdholland * Copyright 1997 Jonathan Stone 526165e63Sdholland * All rights reserved. 626165e63Sdholland * 726165e63Sdholland * Redistribution and use in source and binary forms, with or without 826165e63Sdholland * modification, are permitted provided that the following conditions 926165e63Sdholland * are met: 1026165e63Sdholland * 1. Redistributions of source code must retain the above copyright 1126165e63Sdholland * notice, this list of conditions and the following disclaimer. 1226165e63Sdholland * 2. Redistributions in binary form must reproduce the above copyright 1326165e63Sdholland * notice, this list of conditions and the following disclaimer in the 1426165e63Sdholland * documentation and/or other materials provided with the distribution. 1526165e63Sdholland * 3. All advertising materials mentioning features or use of this software 1626165e63Sdholland * must display the following acknowledgement: 1726165e63Sdholland * This product includes software developed for the NetBSD Project by 1826165e63Sdholland * Jonathan Stone. 1926165e63Sdholland * 4. The name of Jonathan Stone may not be used to endorse 2026165e63Sdholland * or promote products derived from this software without specific prior 2126165e63Sdholland * written permission. 2226165e63Sdholland * 2326165e63Sdholland * THIS SOFTWARE IS PROVIDED BY JONATHAN STONE ``AS IS'' 2426165e63Sdholland * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2526165e63Sdholland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2626165e63Sdholland * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 2726165e63Sdholland * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2826165e63Sdholland * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2926165e63Sdholland * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3026165e63Sdholland * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3126165e63Sdholland * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3226165e63Sdholland * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3326165e63Sdholland * THE POSSIBILITY OF SUCH DAMAGE. 3426165e63Sdholland * 3526165e63Sdholland */ 3626165e63Sdholland 3726165e63Sdholland #include <sys/cdefs.h> 3826165e63Sdholland #if defined(LIBC_SCCS) && !defined(lint) 39*b288bf5cSmartin __RCSID("$NetBSD: label.c,v 1.4 2018/11/20 19:02:07 martin Exp $"); 4026165e63Sdholland #endif 4126165e63Sdholland 4226165e63Sdholland #include <sys/types.h> 4326165e63Sdholland #include <stddef.h> 4426165e63Sdholland #include <errno.h> 4526165e63Sdholland #include <stdio.h> 4626165e63Sdholland #include <fcntl.h> 4726165e63Sdholland #include <util.h> 4826165e63Sdholland #include <unistd.h> 4926165e63Sdholland #include <sys/dkio.h> 5026165e63Sdholland #include <sys/param.h> 5126165e63Sdholland #include <ufs/ffs/fs.h> 5226165e63Sdholland 5326165e63Sdholland #include "defs.h" 5426165e63Sdholland #include "msg_defs.h" 5526165e63Sdholland #include "menu_defs.h" 5626165e63Sdholland 5726165e63Sdholland struct ptn_menu_info { 5826165e63Sdholland int flags; 5926165e63Sdholland #define PIF_SHOW_UNUSED 1 6026165e63Sdholland }; 6126165e63Sdholland 6226165e63Sdholland /* 6326165e63Sdholland * local prototypes 6426165e63Sdholland */ 6526165e63Sdholland static int boringpart(partinfo *, int, int, int); 6626165e63Sdholland static uint32_t getpartoff(uint32_t); 6726165e63Sdholland static uint32_t getpartsize(uint32_t, uint32_t); 6826165e63Sdholland 6926165e63Sdholland static int checklabel(partinfo *, int, int, int, int *, int *); 7026165e63Sdholland static int atofsb(const char *, uint32_t *, uint32_t *); 7126165e63Sdholland 7226165e63Sdholland 7326165e63Sdholland /* 7426165e63Sdholland * Return 1 if partition i in lp should be ignored when checking 7526165e63Sdholland * for overlapping partitions. 7626165e63Sdholland */ 7726165e63Sdholland static int 7826165e63Sdholland boringpart(partinfo *lp, int i, int rawpart, int bsdpart) 7926165e63Sdholland { 8026165e63Sdholland 8126165e63Sdholland if (i == rawpart || i == bsdpart || 8226165e63Sdholland lp[i].pi_fstype == FS_UNUSED || lp[i].pi_size == 0) 8326165e63Sdholland return 1; 8426165e63Sdholland return 0; 8526165e63Sdholland } 8626165e63Sdholland 8726165e63Sdholland 8826165e63Sdholland 8926165e63Sdholland /* 9026165e63Sdholland * Check a sysinst label structure for overlapping partitions. 9126165e63Sdholland * Returns 0 if no overlapping partition found, nonzero otherwise. 9226165e63Sdholland * Sets reference arguments ovly1 and ovly2 to the indices of 9326165e63Sdholland * overlapping partitions if any are found. 9426165e63Sdholland */ 9526165e63Sdholland static int 9626165e63Sdholland checklabel(partinfo *lp, int nparts, int rawpart, int bsdpart, 9726165e63Sdholland int *ovly1, int *ovly2) 9826165e63Sdholland { 9926165e63Sdholland int i; 10026165e63Sdholland int j; 10126165e63Sdholland 10226165e63Sdholland *ovly1 = -1; 10326165e63Sdholland *ovly2 = -1; 10426165e63Sdholland 10526165e63Sdholland for (i = 0; i < nparts - 1; i ++ ) { 10626165e63Sdholland partinfo *ip = &lp[i]; 10726165e63Sdholland uint32_t istart, istop; 10826165e63Sdholland 10926165e63Sdholland /* skip unused or reserved partitions */ 11026165e63Sdholland if (boringpart(lp, i, rawpart, bsdpart)) 11126165e63Sdholland continue; 11226165e63Sdholland 11326165e63Sdholland /* 11426165e63Sdholland * check succeeding partitions for overlap. 11526165e63Sdholland * O(n^2), but n is small (currently <= 16). 11626165e63Sdholland */ 11726165e63Sdholland istart = ip->pi_offset; 11826165e63Sdholland istop = istart + ip->pi_size; 11926165e63Sdholland 12026165e63Sdholland for (j = i+1; j < nparts; j++) { 12126165e63Sdholland partinfo *jp = &lp[j]; 12226165e63Sdholland uint32_t jstart, jstop; 12326165e63Sdholland 12426165e63Sdholland /* skip unused or reserved partitions */ 12526165e63Sdholland if (boringpart(lp, j, rawpart, bsdpart)) 12626165e63Sdholland continue; 12726165e63Sdholland 12826165e63Sdholland jstart = jp->pi_offset; 12926165e63Sdholland jstop = jstart + jp->pi_size; 13026165e63Sdholland 13126165e63Sdholland /* overlap? */ 13226165e63Sdholland if ((istart <= jstart && jstart < istop) || 13326165e63Sdholland (jstart <= istart && istart < jstop)) { 13426165e63Sdholland *ovly1 = i; 13526165e63Sdholland *ovly2 = j; 13626165e63Sdholland return (1); 13726165e63Sdholland } 13826165e63Sdholland } 13926165e63Sdholland } 14026165e63Sdholland 14126165e63Sdholland return (0); 14226165e63Sdholland } 14326165e63Sdholland 144da5a563bSmartin int 145da5a563bSmartin checkoverlap(partinfo *lp, int nparts, int rawpart, int bsdpart) 146da5a563bSmartin { 147da5a563bSmartin int i, j; 148da5a563bSmartin if (checklabel(lp, nparts, rawpart, bsdpart, &i, &j)) { 149da5a563bSmartin msg_display(MSG_partitions_overlap,'a'+i,'a'+j); 150da5a563bSmartin return 1; 151da5a563bSmartin } 152da5a563bSmartin return 0; 153da5a563bSmartin } 154da5a563bSmartin 15526165e63Sdholland static int 15626165e63Sdholland check_one_root(partinfo *lp, int nparts) 15726165e63Sdholland { 15826165e63Sdholland int part; 15926165e63Sdholland int foundroot = 0; 16026165e63Sdholland 16126165e63Sdholland for (part = 0; part < nparts; lp++, part++) { 16226165e63Sdholland #if 0 16326165e63Sdholland if (!PI_ISBSDFS(lp)) 16426165e63Sdholland continue; 16526165e63Sdholland #endif 16626165e63Sdholland if (!(lp->pi_flags & PIF_MOUNT)) 16726165e63Sdholland continue; 16826165e63Sdholland if (strcmp(lp->pi_mount, "/") != 0) 16926165e63Sdholland continue; 17026165e63Sdholland if (foundroot) 17126165e63Sdholland /* Duplicate */ 17226165e63Sdholland return 0; 17326165e63Sdholland foundroot = 1; 17426165e63Sdholland /* Save partition number, a few things need to know it */ 175da5a563bSmartin pm->rootpart = part; 17626165e63Sdholland } 17726165e63Sdholland return foundroot; 17826165e63Sdholland } 17926165e63Sdholland 18026165e63Sdholland static int 18126165e63Sdholland edit_fs_start(menudesc *m, void *arg) 18226165e63Sdholland { 18326165e63Sdholland partinfo *p = arg; 18426165e63Sdholland uint32_t start, end; 18526165e63Sdholland 18626165e63Sdholland start = getpartoff(p->pi_offset); 18726165e63Sdholland if (p->pi_size != 0) { 18826165e63Sdholland /* Try to keep end in the same place */ 18926165e63Sdholland end = p->pi_offset + p->pi_size; 19026165e63Sdholland if (end < start) 19126165e63Sdholland p->pi_size = 0; 19226165e63Sdholland else 19326165e63Sdholland p->pi_size = end - start; 19426165e63Sdholland } 19526165e63Sdholland p->pi_offset = start; 19626165e63Sdholland return 0; 19726165e63Sdholland } 19826165e63Sdholland 19926165e63Sdholland static int 20026165e63Sdholland edit_fs_size(menudesc *m, void *arg) 20126165e63Sdholland { 20226165e63Sdholland partinfo *p = arg; 20326165e63Sdholland uint32_t size; 20426165e63Sdholland 20526165e63Sdholland size = getpartsize(p->pi_offset, p->pi_size); 20626165e63Sdholland if (size == ~0u) 207da5a563bSmartin size = pm->dlsize - p->pi_offset; 20826165e63Sdholland p->pi_size = size; 20926165e63Sdholland if (size == 0) { 21026165e63Sdholland p->pi_offset = 0; 21126165e63Sdholland p->pi_fstype = FS_UNUSED; 21226165e63Sdholland } 21326165e63Sdholland return 0; 21426165e63Sdholland } 21526165e63Sdholland 21626165e63Sdholland void 21726165e63Sdholland set_ptype(partinfo *p, int fstype, int flag) 21826165e63Sdholland { 21926165e63Sdholland p->pi_flags = (p->pi_flags & ~PIF_FFSv2) | flag; 22026165e63Sdholland 22126165e63Sdholland if (p->pi_fstype == fstype) 22226165e63Sdholland return; 22326165e63Sdholland 22426165e63Sdholland p->pi_fstype = fstype; 22526165e63Sdholland if (fstype == FS_BSDFFS || fstype == FS_BSDLFS) { 22626165e63Sdholland p->pi_frag = 8; 22726165e63Sdholland /* 22826165e63Sdholland * match newfs defaults for fragments size: 22926165e63Sdholland * fs size frag size 23026165e63Sdholland * < 20 MB 0.5 KB 23126165e63Sdholland * < 1000 MB 1 KB 23226165e63Sdholland * < 128 GB 2 KB 23326165e63Sdholland * >= 128 GB 4 KB 23426165e63Sdholland */ 23526165e63Sdholland /* note pi_size is uint32_t so we have to avoid overflow */ 23626165e63Sdholland if (p->pi_size < (20 * 1024 * (1024 / 512))) 23726165e63Sdholland p->pi_fsize = 512; 23826165e63Sdholland else if (p->pi_size < (1000 * 1024 * (1024 / 512))) 23926165e63Sdholland p->pi_fsize = 1024; 24026165e63Sdholland else if (p->pi_size < (128 * 1024 * 1024 * (1024 / 512))) 24126165e63Sdholland p->pi_fsize = 2048; 24226165e63Sdholland else 24326165e63Sdholland p->pi_fsize = 4096; 24426165e63Sdholland } else { 24526165e63Sdholland /* zero - fields not used */ 24626165e63Sdholland p->pi_frag = 0; 24726165e63Sdholland p->pi_fsize = 0; 24826165e63Sdholland } 24926165e63Sdholland } 25026165e63Sdholland 25126165e63Sdholland void 25226165e63Sdholland set_bsize(partinfo *p, int size) 25326165e63Sdholland { 25426165e63Sdholland int frags, sz; 25526165e63Sdholland 25626165e63Sdholland sz = p->pi_fsize; 25726165e63Sdholland if (sz <= 0) 25826165e63Sdholland sz = 512; 25926165e63Sdholland frags = size / sz; 26026165e63Sdholland if (frags > 8) 26126165e63Sdholland frags = 8; 26226165e63Sdholland if (frags <= 0) 26326165e63Sdholland frags = 1; 26426165e63Sdholland 26526165e63Sdholland p->pi_frag = frags; 26626165e63Sdholland p->pi_fsize = size / frags; 26726165e63Sdholland } 26826165e63Sdholland 26926165e63Sdholland void 27026165e63Sdholland set_fsize(partinfo *p, int fsize) 27126165e63Sdholland { 27226165e63Sdholland int bsz = p->pi_fsize * p->pi_frag; 27326165e63Sdholland int frags = bsz / fsize; 27426165e63Sdholland 27526165e63Sdholland if (frags > 8) 27626165e63Sdholland frags = 8; 27726165e63Sdholland if (frags <= 0) 27826165e63Sdholland frags = 1; 27926165e63Sdholland 28026165e63Sdholland p->pi_fsize = fsize; 28126165e63Sdholland p->pi_frag = frags; 28226165e63Sdholland } 28326165e63Sdholland 28426165e63Sdholland static int 28526165e63Sdholland edit_fs_isize(menudesc *m, void *arg) 28626165e63Sdholland { 28726165e63Sdholland partinfo *p = arg; 28826165e63Sdholland char answer[12]; 28926165e63Sdholland 29026165e63Sdholland snprintf(answer, sizeof answer, "%u", p->pi_isize); 29126165e63Sdholland msg_prompt_win(MSG_fs_isize, -1, 18, 0, 0, 29226165e63Sdholland answer, answer, sizeof answer); 29326165e63Sdholland p->pi_isize = atol(answer); 29426165e63Sdholland return 0; 29526165e63Sdholland } 29626165e63Sdholland 29726165e63Sdholland 29826165e63Sdholland static int 29926165e63Sdholland edit_fs_preserve(menudesc *m, void *arg) 30026165e63Sdholland { 30126165e63Sdholland partinfo *p = arg; 30226165e63Sdholland 30326165e63Sdholland p->pi_flags ^= PIF_NEWFS; 30426165e63Sdholland return 0; 30526165e63Sdholland } 30626165e63Sdholland 30726165e63Sdholland static int 30826165e63Sdholland edit_fs_mount(menudesc *m, void *arg) 30926165e63Sdholland { 31026165e63Sdholland partinfo *p = arg; 31126165e63Sdholland 31226165e63Sdholland p->pi_flags ^= PIF_MOUNT; 31326165e63Sdholland return 0; 31426165e63Sdholland } 31526165e63Sdholland 31626165e63Sdholland static int 31726165e63Sdholland edit_fs_mountpt(menudesc *m, void *arg) 31826165e63Sdholland { 31926165e63Sdholland partinfo *p = arg; 32026165e63Sdholland 32126165e63Sdholland msg_prompt_win(MSG_mountpoint, -1, 18, 0, 0, 32226165e63Sdholland p->pi_mount, p->pi_mount, sizeof p->pi_mount); 32326165e63Sdholland 32426165e63Sdholland if (p->pi_mount[0] == ' ' || strcmp(p->pi_mount, "none") == 0) { 32526165e63Sdholland p->pi_mount[0] = 0; 32626165e63Sdholland return 0; 32726165e63Sdholland } 32826165e63Sdholland 32926165e63Sdholland if (p->pi_mount[0] != '/') { 33026165e63Sdholland memmove(p->pi_mount + 1, p->pi_mount, 33126165e63Sdholland sizeof p->pi_mount - 1); 33226165e63Sdholland p->pi_mount[sizeof p->pi_mount - 1] = 0; 33326165e63Sdholland p->pi_mount[0] = '/'; 33426165e63Sdholland } 33526165e63Sdholland 33626165e63Sdholland return 0; 33726165e63Sdholland } 33826165e63Sdholland 33926165e63Sdholland static int 34026165e63Sdholland edit_restore(menudesc *m, void *arg) 34126165e63Sdholland { 34226165e63Sdholland partinfo *p = arg; 34326165e63Sdholland 34426165e63Sdholland p->pi_flags |= PIF_RESET; 34526165e63Sdholland return 1; 34626165e63Sdholland } 34726165e63Sdholland 34826165e63Sdholland static int 34926165e63Sdholland set_fstype(menudesc *m, void *arg) 35026165e63Sdholland { 35126165e63Sdholland partinfo *p = arg; 35226165e63Sdholland 35326165e63Sdholland if (m->cursel == FS_UNUSED) 35426165e63Sdholland memset(p, 0, sizeof *p); 35526165e63Sdholland else 35626165e63Sdholland p->pi_fstype = m->cursel; 35726165e63Sdholland return 1; 35826165e63Sdholland } 35926165e63Sdholland 36026165e63Sdholland static void 36126165e63Sdholland get_fstype(menudesc *m, void *arg) 36226165e63Sdholland { 36326165e63Sdholland partinfo *p = arg; 36426165e63Sdholland 36526165e63Sdholland m->cursel = p->pi_fstype; 36626165e63Sdholland } 36726165e63Sdholland 36826165e63Sdholland static void set_ptn_header(menudesc *m, void *arg); 36926165e63Sdholland static void set_ptn_label(menudesc *m, int opt, void *arg); 37026165e63Sdholland int all_fstype_menu = -1; 37126165e63Sdholland 372da5a563bSmartin int 37326165e63Sdholland edit_ptn(menudesc *menu, void *arg) 37426165e63Sdholland { 37526165e63Sdholland static menu_ent fs_fields[] = { 37626165e63Sdholland #define PTN_MENU_FSKIND 0 377*b288bf5cSmartin { .opt_menu=MENU_selfskind, .opt_flags=OPT_SUB }, 37826165e63Sdholland #define PTN_MENU_START 1 379*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_start }, 38026165e63Sdholland #define PTN_MENU_SIZE 2 381*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_size }, 38226165e63Sdholland #define PTN_MENU_END 3 383*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_flags=OPT_IGNORE }, /* displays 'end' */ 38426165e63Sdholland #define PTN_MENU_NEWFS 4 385*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_preserve }, 38626165e63Sdholland #define PTN_MENU_ISIZE 5 387*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_isize }, 38826165e63Sdholland #define PTN_MENU_BSIZE 6 389*b288bf5cSmartin { .opt_menu=MENU_selbsize, .opt_flags=OPT_SUB }, 39026165e63Sdholland #define PTN_MENU_FSIZE 7 391*b288bf5cSmartin { .opt_menu=MENU_selfsize, .opt_flags=OPT_SUB }, 39226165e63Sdholland #define PTN_MENU_MOUNT 8 393*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_mount }, 39426165e63Sdholland #define PTN_MENU_MOUNTOPT 9 395*b288bf5cSmartin { .opt_menu=MENU_mountoptions, .opt_flags=OPT_SUB }, 39626165e63Sdholland #define PTN_MENU_MOUNTPT 10 397*b288bf5cSmartin { .opt_menu=OPT_NOMENU, .opt_action=edit_fs_mountpt }, 398*b288bf5cSmartin { .opt_name=MSG_askunits, .opt_menu=MENU_sizechoice, 399*b288bf5cSmartin .opt_flags=OPT_SUB }, 400*b288bf5cSmartin { .opt_name=MSG_restore, .opt_menu=OPT_NOMENU, 401*b288bf5cSmartin .opt_action=edit_restore}, 40226165e63Sdholland }; 40326165e63Sdholland static int fspart_menu = -1; 40426165e63Sdholland static menu_ent all_fstypes[FSMAXTYPES]; 40526165e63Sdholland partinfo *p, p_save; 40626165e63Sdholland unsigned int i; 40726165e63Sdholland 40826165e63Sdholland if (fspart_menu == -1) { 40926165e63Sdholland fspart_menu = new_menu(NULL, fs_fields, nelem(fs_fields), 41026165e63Sdholland 0, -1, 0, 70, 41126165e63Sdholland MC_NOBOX | MC_NOCLEAR | MC_SCROLL, 41226165e63Sdholland set_ptn_header, set_ptn_label, NULL, 41326165e63Sdholland NULL, MSG_partition_sizes_ok); 41426165e63Sdholland } 41526165e63Sdholland 41626165e63Sdholland if (all_fstype_menu == -1) { 41726165e63Sdholland for (i = 0; i < nelem(all_fstypes); i++) { 41826165e63Sdholland all_fstypes[i].opt_name = getfslabelname(i); 41926165e63Sdholland all_fstypes[i].opt_menu = OPT_NOMENU; 42026165e63Sdholland all_fstypes[i].opt_flags = 0; 42126165e63Sdholland all_fstypes[i].opt_action = set_fstype; 42226165e63Sdholland } 42326165e63Sdholland all_fstype_menu = new_menu(MSG_Select_the_type, 42426165e63Sdholland all_fstypes, nelem(all_fstypes), 42526165e63Sdholland 30, 6, 10, 0, MC_SUBMENU | MC_SCROLL, 42626165e63Sdholland get_fstype, NULL, NULL, NULL, MSG_unchanged); 42726165e63Sdholland } 42826165e63Sdholland 429da5a563bSmartin p = pm->bsdlabel + menu->cursel; 43026165e63Sdholland p->pi_flags &= ~PIF_RESET; 43126165e63Sdholland p_save = *p; 43226165e63Sdholland for (;;) { 43326165e63Sdholland process_menu(fspart_menu, p); 43426165e63Sdholland if (!(p->pi_flags & PIF_RESET)) 43526165e63Sdholland break; 43626165e63Sdholland *p = p_save; 43726165e63Sdholland } 43826165e63Sdholland 43926165e63Sdholland return 0; 44026165e63Sdholland } 44126165e63Sdholland 44226165e63Sdholland static void 44326165e63Sdholland set_ptn_header(menudesc *m, void *arg) 44426165e63Sdholland { 44526165e63Sdholland partinfo *p = arg; 44626165e63Sdholland int i; 44726165e63Sdholland int t; 44826165e63Sdholland 44926165e63Sdholland msg_clear(); 450da5a563bSmartin msg_table_add(MSG_edfspart, 'a' + (p - pm->bsdlabel)); 45126165e63Sdholland 45226165e63Sdholland /* Determine which of the properties can be changed */ 45326165e63Sdholland for (i = PTN_MENU_START; i <= PTN_MENU_MOUNTPT; i++) { 45426165e63Sdholland /* Default to disabled... */ 45526165e63Sdholland m->opts[i].opt_flags |= OPT_IGNORE; 45626165e63Sdholland t = p->pi_fstype; 45726165e63Sdholland if (i == PTN_MENU_END) 45826165e63Sdholland /* The 'end address' is calculated from the size */ 45926165e63Sdholland continue; 46026165e63Sdholland if (t == FS_UNUSED || (t == FS_SWAP && i > PTN_MENU_END)) { 46126165e63Sdholland /* Nothing after 'size' can be set for swap/unused */ 46226165e63Sdholland p->pi_flags &= ~(PIF_NEWFS | PIF_MOUNT); 46326165e63Sdholland p->pi_mount[0] = 0; 46426165e63Sdholland continue; 46526165e63Sdholland } 46626165e63Sdholland if (i == PTN_MENU_NEWFS && t != FS_BSDFFS && t != FS_BSDLFS 46726165e63Sdholland && t != FS_APPLEUFS) { 46826165e63Sdholland /* Can only newfs UFS and LFS filesystems */ 46926165e63Sdholland p->pi_flags &= ~PIF_NEWFS; 47026165e63Sdholland continue; 47126165e63Sdholland } 47226165e63Sdholland if (i >= PTN_MENU_ISIZE && i <= PTN_MENU_FSIZE) { 47326165e63Sdholland /* Parameters for newfs... */ 47426165e63Sdholland if (!(p->pi_flags & PIF_NEWFS)) 47526165e63Sdholland /* Not if we aren't going to run newfs */ 47626165e63Sdholland continue; 47726165e63Sdholland if (t == FS_APPLEUFS && i != PTN_MENU_ISIZE) 47826165e63Sdholland /* Can only set # inodes for appleufs */ 47926165e63Sdholland continue; 48026165e63Sdholland if (t == FS_BSDLFS && i != PTN_MENU_BSIZE) 48126165e63Sdholland /* LFS doesn't have fragments */ 48226165e63Sdholland continue; 48326165e63Sdholland } 48426165e63Sdholland /* Ok: we want this one */ 48526165e63Sdholland m->opts[i].opt_flags &= ~OPT_IGNORE; 48626165e63Sdholland } 48726165e63Sdholland } 48826165e63Sdholland 48926165e63Sdholland static void 49026165e63Sdholland disp_sector_count(menudesc *m, msg fmt, uint s) 49126165e63Sdholland { 492da5a563bSmartin uint ms = MEG / pm->sectorsize; 49326165e63Sdholland 49426165e63Sdholland wprintw(m->mw, msg_string(fmt), 495da5a563bSmartin s / ms, s / pm->dlcylsize, s % pm->dlcylsize ? '*' : ' ', s ); 49626165e63Sdholland } 49726165e63Sdholland 49826165e63Sdholland static void 49926165e63Sdholland set_ptn_label(menudesc *m, int opt, void *arg) 50026165e63Sdholland { 50126165e63Sdholland partinfo *p = arg; 50226165e63Sdholland const char *c; 50326165e63Sdholland 50426165e63Sdholland if (m->opts[opt].opt_flags & OPT_IGNORE 50526165e63Sdholland && (opt != PTN_MENU_END || p->pi_fstype == FS_UNUSED)) { 50626165e63Sdholland wprintw(m->mw, " -"); 50726165e63Sdholland return; 50826165e63Sdholland } 50926165e63Sdholland 51026165e63Sdholland switch (opt) { 51126165e63Sdholland case PTN_MENU_FSKIND: 51226165e63Sdholland if (p->pi_fstype == FS_BSDFFS) 51326165e63Sdholland if (p->pi_flags & PIF_FFSv2) 51426165e63Sdholland c = "FFSv2"; 51526165e63Sdholland else 51626165e63Sdholland c = "FFSv1"; 51726165e63Sdholland else 51826165e63Sdholland c = getfslabelname(p->pi_fstype); 51926165e63Sdholland wprintw(m->mw, msg_string(MSG_fstype_fmt), c); 52026165e63Sdholland break; 52126165e63Sdholland case PTN_MENU_START: 52226165e63Sdholland disp_sector_count(m, MSG_start_fmt, p->pi_offset); 52326165e63Sdholland break; 52426165e63Sdholland case PTN_MENU_SIZE: 52526165e63Sdholland disp_sector_count(m, MSG_size_fmt, p->pi_size); 52626165e63Sdholland break; 52726165e63Sdholland case PTN_MENU_END: 52826165e63Sdholland disp_sector_count(m, MSG_end_fmt, p->pi_offset + p->pi_size); 52926165e63Sdholland break; 53026165e63Sdholland case PTN_MENU_NEWFS: 53126165e63Sdholland wprintw(m->mw, msg_string(MSG_newfs_fmt), 53226165e63Sdholland msg_string(p->pi_flags & PIF_NEWFS ? MSG_Yes : MSG_No)); 53326165e63Sdholland break; 53426165e63Sdholland case PTN_MENU_ISIZE: 53526165e63Sdholland wprintw(m->mw, msg_string(p->pi_isize > 0 ? 53626165e63Sdholland MSG_isize_fmt : MSG_isize_fmt_dflt), p->pi_isize); 53726165e63Sdholland break; 53826165e63Sdholland case PTN_MENU_BSIZE: 53926165e63Sdholland wprintw(m->mw, msg_string(MSG_bsize_fmt), 54026165e63Sdholland p->pi_fsize * p->pi_frag); 54126165e63Sdholland break; 54226165e63Sdholland case PTN_MENU_FSIZE: 54326165e63Sdholland wprintw(m->mw, msg_string(MSG_fsize_fmt), p->pi_fsize); 54426165e63Sdholland break; 54526165e63Sdholland case PTN_MENU_MOUNT: 54626165e63Sdholland wprintw(m->mw, msg_string(MSG_mount_fmt), 54726165e63Sdholland msg_string(p->pi_flags & PIF_MOUNT ? MSG_Yes : MSG_No)); 54826165e63Sdholland break; 54926165e63Sdholland case PTN_MENU_MOUNTOPT: 55026165e63Sdholland wprintw(m->mw, "%s", msg_string(MSG_mount_options_fmt)); 55126165e63Sdholland if (p->pi_flags & PIF_ASYNC) 55226165e63Sdholland wprintw(m->mw, "async "); 55326165e63Sdholland if (p->pi_flags & PIF_NOATIME) 55426165e63Sdholland wprintw(m->mw, "noatime "); 55526165e63Sdholland if (p->pi_flags & PIF_NODEV) 55626165e63Sdholland wprintw(m->mw, "nodev "); 55726165e63Sdholland if (p->pi_flags & PIF_NODEVMTIME) 55826165e63Sdholland wprintw(m->mw, "nodevmtime "); 55926165e63Sdholland if (p->pi_flags & PIF_NOEXEC) 56026165e63Sdholland wprintw(m->mw, "noexec "); 56126165e63Sdholland if (p->pi_flags & PIF_NOSUID) 56226165e63Sdholland wprintw(m->mw, "nosuid "); 56326165e63Sdholland if (p->pi_flags & PIF_LOG) 56426165e63Sdholland wprintw(m->mw, "log "); 56526165e63Sdholland break; 56626165e63Sdholland case PTN_MENU_MOUNTPT: 56726165e63Sdholland wprintw(m->mw, msg_string(MSG_mountpt_fmt), p->pi_mount); 56826165e63Sdholland break; 56926165e63Sdholland } 57026165e63Sdholland } 57126165e63Sdholland 57226165e63Sdholland static int 57326165e63Sdholland show_all_unused(menudesc *m, void *arg) 57426165e63Sdholland { 57526165e63Sdholland struct ptn_menu_info *pi = arg; 57626165e63Sdholland 57726165e63Sdholland pi->flags |= PIF_SHOW_UNUSED; 57826165e63Sdholland return 0; 57926165e63Sdholland } 58026165e63Sdholland 58126165e63Sdholland static void 58226165e63Sdholland set_label_texts(menudesc *menu, void *arg) 58326165e63Sdholland { 58426165e63Sdholland struct ptn_menu_info *pi = arg; 58526165e63Sdholland menu_ent *m; 58626165e63Sdholland int ptn, show_unused_ptn; 58726165e63Sdholland int rawptn = getrawpartition(); 58826165e63Sdholland int maxpart = getmaxpartitions(); 58926165e63Sdholland 59026165e63Sdholland msg_display(MSG_fspart); 59126165e63Sdholland msg_table_add(MSG_fspart_header, multname, multname, multname); 59226165e63Sdholland 59326165e63Sdholland for (show_unused_ptn = 0, ptn = 0; ptn < maxpart; ptn++) { 59426165e63Sdholland m = &menu->opts[ptn]; 59526165e63Sdholland m->opt_menu = OPT_NOMENU; 59626165e63Sdholland m->opt_name = NULL; 59726165e63Sdholland m->opt_action = edit_ptn; 59826165e63Sdholland if (ptn == rawptn 59926165e63Sdholland #ifdef PART_BOOT 60026165e63Sdholland || ptn == PART_BOOT 60126165e63Sdholland #endif 60226165e63Sdholland || ptn == PART_C) { 60326165e63Sdholland m->opt_flags = OPT_IGNORE; 60426165e63Sdholland } else { 60526165e63Sdholland m->opt_flags = 0; 606da5a563bSmartin if (pm->bsdlabel[ptn].pi_fstype == FS_UNUSED) 60726165e63Sdholland continue; 60826165e63Sdholland } 60926165e63Sdholland show_unused_ptn = ptn + 2; 61026165e63Sdholland } 61126165e63Sdholland 61226165e63Sdholland if (!(pi->flags & PIF_SHOW_UNUSED) && ptn > show_unused_ptn) { 61326165e63Sdholland ptn = show_unused_ptn; 61426165e63Sdholland m = &menu->opts[ptn]; 61526165e63Sdholland m->opt_name = MSG_show_all_unused_partitions; 61626165e63Sdholland m->opt_action = show_all_unused; 61726165e63Sdholland ptn++; 61826165e63Sdholland } 61926165e63Sdholland 62026165e63Sdholland m = &menu->opts[ptn]; 62126165e63Sdholland m->opt_menu = MENU_sizechoice; 62226165e63Sdholland m->opt_flags = OPT_SUB; 62326165e63Sdholland m->opt_action = NULL; 62426165e63Sdholland m->opt_name = MSG_askunits; 62526165e63Sdholland 62626165e63Sdholland menu->numopts = ptn + 1; 62726165e63Sdholland } 62826165e63Sdholland 62926165e63Sdholland /* 63026165e63Sdholland * Check a disklabel. 63126165e63Sdholland * If there are overlapping active partitions, 63226165e63Sdholland * Ask the user if they want to edit the partition or give up. 63326165e63Sdholland */ 63426165e63Sdholland int 63526165e63Sdholland edit_and_check_label(partinfo *lp, int nparts, int rawpart, int bsdpart) 63626165e63Sdholland { 63726165e63Sdholland static struct menu_ent *menu; 63826165e63Sdholland static int menu_no = -1; 63926165e63Sdholland static struct ptn_menu_info pi; 64026165e63Sdholland int maxpart = getmaxpartitions(); 64126165e63Sdholland 64226165e63Sdholland if (menu == NULL) { 64326165e63Sdholland menu = malloc((maxpart + 1) * sizeof *menu); 64426165e63Sdholland if (!menu) 64526165e63Sdholland return 1; 64626165e63Sdholland } 64726165e63Sdholland 64826165e63Sdholland if (menu_no == -1) { 64926165e63Sdholland menu_no = new_menu(NULL, menu, maxpart + 1, 65026165e63Sdholland 0, -1, maxpart + 2, 74, 65126165e63Sdholland MC_ALWAYS_SCROLL | MC_NOBOX | MC_DFLTEXIT, 65226165e63Sdholland set_label_texts, fmt_fspart, NULL, NULL, 65326165e63Sdholland MSG_partition_sizes_ok); 65426165e63Sdholland } 65526165e63Sdholland 65626165e63Sdholland if (menu_no < 0) 65726165e63Sdholland return 1; 65826165e63Sdholland 65926165e63Sdholland pi.flags = 0; 660da5a563bSmartin pm->current_cylsize = pm->dlcylsize; 66126165e63Sdholland 66226165e63Sdholland for (;;) { 66326165e63Sdholland /* first give the user the option to edit the label... */ 66426165e63Sdholland process_menu(menu_no, &pi); 66526165e63Sdholland 66626165e63Sdholland /* User thinks the label is OK. */ 66726165e63Sdholland /* check we have a single root fs */ 668da5a563bSmartin if (check_one_root(lp, nparts) == 0 && partman_go == 0) 66926165e63Sdholland msg_display(MSG_must_be_one_root); 67026165e63Sdholland else 67126165e63Sdholland /* Check for overlaps */ 672da5a563bSmartin if (checkoverlap(lp, nparts, rawpart, bsdpart) == 0) 67326165e63Sdholland return 1; 67426165e63Sdholland 67526165e63Sdholland /*XXX ???*/ 67626165e63Sdholland msg_display_add(MSG_edit_partitions_again); 67786ffd738Smartin if (!ask_yesno(NULL)) 67826165e63Sdholland return(0); 67926165e63Sdholland } 68026165e63Sdholland 68126165e63Sdholland /*NOTREACHED*/ 68226165e63Sdholland } 68326165e63Sdholland 68426165e63Sdholland /* 68526165e63Sdholland * Read a label from disk into a sysinst label structure. 68626165e63Sdholland */ 68726165e63Sdholland int 68826165e63Sdholland incorelabel(const char *dkname, partinfo *lp) 68926165e63Sdholland { 69026165e63Sdholland struct disklabel lab; 69126165e63Sdholland int i, maxpart; 69226165e63Sdholland struct partition *pp; 69326165e63Sdholland int fd; 69426165e63Sdholland char buf[64]; 69526165e63Sdholland 69626165e63Sdholland if (get_real_geom(dkname, &lab) == 0) 69726165e63Sdholland return -1; 69826165e63Sdholland 69926165e63Sdholland touchwin(stdscr); 70026165e63Sdholland maxpart = getmaxpartitions(); 70126165e63Sdholland if (maxpart > MAXPARTITIONS) 70226165e63Sdholland maxpart = MAXPARTITIONS; 70326165e63Sdholland if (maxpart > lab.d_npartitions) 70426165e63Sdholland maxpart = lab.d_npartitions; 70526165e63Sdholland 70626165e63Sdholland /* 70726165e63Sdholland * Historically sysinst writes the name to d_typename rather 70826165e63Sdholland * than d_diskname. Who knows why, but pull the value back here. 70926165e63Sdholland */ 71026165e63Sdholland if (lab.d_typename[0] != 0 && strcmp(lab.d_typename, "unknown") != 0) 711da5a563bSmartin strlcpy(pm->bsddiskname, lab.d_typename, sizeof pm->bsddiskname); 71226165e63Sdholland 71326165e63Sdholland fd = opendisk(dkname, O_RDONLY, buf, sizeof buf, 0); 71426165e63Sdholland pp = &lab.d_partitions[0]; 71526165e63Sdholland for (i = 0; i < maxpart; lp++, pp++, i++) { 71626165e63Sdholland lp->pi_partition = *pp; 71726165e63Sdholland if (lp->pi_fstype >= FSMAXTYPES) 71826165e63Sdholland lp->pi_fstype = FS_OTHER; 71926165e63Sdholland strlcpy(lp->pi_mount, get_last_mounted(fd, pp->p_offset, lp), 72026165e63Sdholland sizeof lp->pi_mount); 72126165e63Sdholland } 72226165e63Sdholland if (fd != -1) 72326165e63Sdholland close(fd); 72426165e63Sdholland 72526165e63Sdholland return 0; 72626165e63Sdholland } 72726165e63Sdholland 72826165e63Sdholland /* 72926165e63Sdholland * Try to get 'last mounted on' (or equiv) from fs superblock. 73026165e63Sdholland */ 73126165e63Sdholland const char * 73226165e63Sdholland get_last_mounted(int fd, int partstart, partinfo *lp) 73326165e63Sdholland { 73426165e63Sdholland static char sblk[SBLOCKSIZE]; /* is this enough? */ 73526165e63Sdholland struct fs *SB = (struct fs *)sblk; 73626165e63Sdholland static const int sblocks[] = SBLOCKSEARCH; 73726165e63Sdholland const int *sbp; 73826165e63Sdholland char *cp; 73926165e63Sdholland const char *mnt = NULL; 74026165e63Sdholland int len; 74126165e63Sdholland 74226165e63Sdholland if (fd == -1) 74326165e63Sdholland return ""; 74426165e63Sdholland 74526165e63Sdholland /* Check UFS1/2 (and hence LFS) superblock */ 74626165e63Sdholland for (sbp = sblocks; mnt == NULL && *sbp != -1; sbp++) { 74726165e63Sdholland if (pread(fd, sblk, sizeof sblk, 74826165e63Sdholland partstart * (off_t)512 + *sbp) != sizeof sblk) 74926165e63Sdholland continue; 75026165e63Sdholland /* Maybe we should validate the checksum??? */ 75126165e63Sdholland switch (SB->fs_magic) { 75226165e63Sdholland case FS_UFS1_MAGIC: 75326165e63Sdholland case FS_UFS1_MAGIC_SWAPPED: 75426165e63Sdholland if (!(SB->fs_old_flags & FS_FLAGS_UPDATED)) { 75526165e63Sdholland if (*sbp == SBLOCK_UFS1) 75626165e63Sdholland mnt = (const char *)SB->fs_fsmnt; 75726165e63Sdholland } else { 75826165e63Sdholland /* Check we have the main superblock */ 75926165e63Sdholland if (SB->fs_sblockloc == *sbp) 76026165e63Sdholland mnt = (const char *)SB->fs_fsmnt; 76126165e63Sdholland } 76226165e63Sdholland continue; 76326165e63Sdholland case FS_UFS2_MAGIC: 76426165e63Sdholland case FS_UFS2_MAGIC_SWAPPED: 76526165e63Sdholland /* Check we have the main superblock */ 76626165e63Sdholland if (SB->fs_sblockloc == *sbp) { 76726165e63Sdholland mnt = (const char *)SB->fs_fsmnt; 76826165e63Sdholland if (lp != NULL) 76926165e63Sdholland lp->pi_flags |= PIF_FFSv2; 77026165e63Sdholland } 77126165e63Sdholland continue; 77226165e63Sdholland } 77326165e63Sdholland 77426165e63Sdholland #if 0 /* Requires fs/ext2fs/ext2fs.h which collides badly... */ 77526165e63Sdholland if ((struct ext2fs *)sblk)->e2fs_magic == E2FS_MAGIC) { 77626165e63Sdholland mnt = ((struct ext2fs *)sblk)->e2fs_fsmnt; 77726165e63Sdholland continue; 77826165e63Sdholland } 77926165e63Sdholland #endif 78026165e63Sdholland if (*sbp != 0) 78126165e63Sdholland continue; 78226165e63Sdholland 78326165e63Sdholland /* If start of partition check for other fs types */ 78426165e63Sdholland if (sblk[0x42] == 0x29 && memcmp(sblk + 0x52, "FAT", 3) == 0) { 78526165e63Sdholland /* Probably a FAT filesystem, report volume name */ 78626165e63Sdholland cp = strchr(sblk + 0x47, ' '); 78726165e63Sdholland if (cp == NULL || cp - (sblk + 0x47) > 11) 78826165e63Sdholland cp = sblk + 0x47 + 11; 78926165e63Sdholland *cp = 0; 79026165e63Sdholland return sblk + 0x47; 79126165e63Sdholland } 79226165e63Sdholland } 79326165e63Sdholland 79426165e63Sdholland if (mnt == NULL) 79526165e63Sdholland return ""; 79626165e63Sdholland 79726165e63Sdholland /* If sysinst mounted this last then strip prefix */ 79826165e63Sdholland len = strlen(targetroot_mnt); 79926165e63Sdholland if (memcmp(mnt, targetroot_mnt, len) == 0) { 80026165e63Sdholland if (mnt[len] == 0) 80126165e63Sdholland return "/"; 80226165e63Sdholland if (mnt[len] == '/') 80326165e63Sdholland return mnt + len; 80426165e63Sdholland } 80526165e63Sdholland return mnt; 80626165e63Sdholland #undef SB 80726165e63Sdholland } 80826165e63Sdholland 80926165e63Sdholland /* Ask for a partition offset, check bounds and do the needed roundups */ 81026165e63Sdholland static uint32_t 81126165e63Sdholland getpartoff(uint32_t defpartstart) 81226165e63Sdholland { 81326165e63Sdholland char defsize[20], isize[20], maxpartc; 81426165e63Sdholland uint32_t i; 81526165e63Sdholland uint32_t localsizemult; 81626165e63Sdholland int partn; 81726165e63Sdholland const char *errmsg = "\n"; 81826165e63Sdholland 81926165e63Sdholland maxpartc = 'a' + getmaxpartitions() - 1; 82026165e63Sdholland for (;;) { 82126165e63Sdholland snprintf(defsize, sizeof defsize, "%d", defpartstart/sizemult); 82226165e63Sdholland msg_prompt_win(MSG_label_offset, -1, 13, 70, 9, 82326165e63Sdholland (defpartstart > 0) ? defsize : NULL, isize, sizeof isize, 82426165e63Sdholland errmsg, maxpartc, maxpartc, multname); 82526165e63Sdholland if (strcmp(defsize, isize) == 0) 82626165e63Sdholland /* Don't do rounding if default accepted */ 82726165e63Sdholland return defpartstart; 82826165e63Sdholland if (isize[1] == '\0' && isize[0] >= 'a' && 82926165e63Sdholland isize[0] <= maxpartc) { 83026165e63Sdholland partn = isize[0] - 'a'; 831da5a563bSmartin i = pm->bsdlabel[partn].pi_size + pm->bsdlabel[partn].pi_offset; 83226165e63Sdholland localsizemult = 1; 83326165e63Sdholland } else if (atoi(isize) == -1) { 834da5a563bSmartin i = pm->ptstart; 83526165e63Sdholland localsizemult = 1; 83626165e63Sdholland } else { 83726165e63Sdholland if (atofsb(isize, &i, &localsizemult)) { 83826165e63Sdholland errmsg = msg_string(MSG_invalid_sector_number); 83926165e63Sdholland continue; 84026165e63Sdholland } 84126165e63Sdholland } 84226165e63Sdholland /* round to cylinder size if localsizemult != 1 */ 843da5a563bSmartin i = NUMSEC(i/localsizemult, localsizemult, pm->dlcylsize); 84426165e63Sdholland /* Adjust to start of slice if needed */ 845da5a563bSmartin if ((i < pm->ptstart && (pm->ptstart - i) < localsizemult) || 846da5a563bSmartin (i > pm->ptstart && (i - pm->ptstart) < localsizemult)) { 847da5a563bSmartin i = pm->ptstart; 84826165e63Sdholland } 849da5a563bSmartin if (i <= pm->dlsize) 85026165e63Sdholland break; 85126165e63Sdholland errmsg = msg_string(MSG_startoutsidedisk); 85226165e63Sdholland } 85326165e63Sdholland return i; 85426165e63Sdholland } 85526165e63Sdholland 85626165e63Sdholland 85726165e63Sdholland /* Ask for a partition size, check bounds and do the needed roundups */ 85826165e63Sdholland static uint32_t 85926165e63Sdholland getpartsize(uint32_t partstart, uint32_t defpartsize) 86026165e63Sdholland { 86126165e63Sdholland char dsize[20], isize[20], maxpartc; 86226165e63Sdholland const char *errmsg = "\n"; 86326165e63Sdholland uint32_t i, partend, localsizemult; 864da5a563bSmartin uint32_t fsptend = pm->ptstart + pm->ptsize; 86526165e63Sdholland int partn; 86626165e63Sdholland 86726165e63Sdholland maxpartc = 'a' + getmaxpartitions() - 1; 86826165e63Sdholland for (;;) { 86926165e63Sdholland snprintf(dsize, sizeof dsize, "%d", defpartsize/sizemult); 87026165e63Sdholland msg_prompt_win(MSG_label_size, -1, 12, 70, 9, 87126165e63Sdholland (defpartsize != 0) ? dsize : 0, isize, sizeof isize, 87226165e63Sdholland errmsg, maxpartc, multname); 87326165e63Sdholland if (strcmp(isize, dsize) == 0) 87426165e63Sdholland return defpartsize; 87526165e63Sdholland if (isize[1] == '\0' && isize[0] >= 'a' && 87626165e63Sdholland isize[0] <= maxpartc) { 87726165e63Sdholland partn = isize[0] - 'a'; 878da5a563bSmartin i = pm->bsdlabel[partn].pi_offset - partstart; 87926165e63Sdholland localsizemult = 1; 88026165e63Sdholland } else if (atoi(isize) == -1) { 88126165e63Sdholland i = fsptend - partstart; 88226165e63Sdholland localsizemult = 1; 88326165e63Sdholland } else { 88426165e63Sdholland if (atofsb(isize, &i, &localsizemult)) { 88526165e63Sdholland errmsg = msg_string(MSG_invalid_sector_number); 88626165e63Sdholland continue; 88726165e63Sdholland } 88826165e63Sdholland } 88926165e63Sdholland /* 89026165e63Sdholland * partend is aligned to a cylinder if localsizemult 89126165e63Sdholland * is not 1 sector 89226165e63Sdholland */ 89326165e63Sdholland partend = NUMSEC((partstart + i) / localsizemult, 894da5a563bSmartin localsizemult, pm->dlcylsize); 89526165e63Sdholland /* Align to end-of-disk or end-of-slice if close enough */ 896da5a563bSmartin if (partend > (pm->dlsize - localsizemult) 897da5a563bSmartin && partend < (pm->dlsize + localsizemult)) 898da5a563bSmartin partend = pm->dlsize; 89926165e63Sdholland if (partend > (fsptend - localsizemult) 90026165e63Sdholland && partend < (fsptend + localsizemult)) 90126165e63Sdholland partend = fsptend; 90226165e63Sdholland /* sanity checks */ 903da5a563bSmartin if (partend > pm->dlsize) { 904da5a563bSmartin partend = pm->dlsize; 90526165e63Sdholland msg_prompt_win(MSG_endoutsidedisk, -1, 13, 70, 6, 90626165e63Sdholland NULL, isize, 1, 90726165e63Sdholland (partend - partstart) / sizemult, multname); 90826165e63Sdholland } 90926165e63Sdholland if (partend < partstart) 91026165e63Sdholland return 0; 91126165e63Sdholland return (partend - partstart); 91226165e63Sdholland } 91326165e63Sdholland /* NOTREACHED */ 91426165e63Sdholland } 91526165e63Sdholland 91626165e63Sdholland /* 91726165e63Sdholland * convert a string to a number of sectors, with a possible unit 91826165e63Sdholland * 150M = 150 Megabytes 91926165e63Sdholland * 2000c = 2000 cylinders 92026165e63Sdholland * 150256s = 150256 sectors 92126165e63Sdholland * Without units, use the default (sizemult) 92226165e63Sdholland * returns the number of sectors, and the unit used (for roundups). 92326165e63Sdholland */ 92426165e63Sdholland 92526165e63Sdholland static int 92626165e63Sdholland atofsb(const char *str, uint32_t *p_val, uint32_t *localsizemult) 92726165e63Sdholland { 92826165e63Sdholland int i; 92926165e63Sdholland uint32_t val; 93026165e63Sdholland 93126165e63Sdholland *localsizemult = sizemult; 93226165e63Sdholland if (str[0] == '\0') { 93326165e63Sdholland return 1; 93426165e63Sdholland } 93526165e63Sdholland val = 0; 93626165e63Sdholland for (i = 0; str[i] != '\0'; i++) { 93726165e63Sdholland if (str[i] >= '0' && str[i] <= '9') { 93826165e63Sdholland val = val * 10 + str[i] - '0'; 93926165e63Sdholland continue; 94026165e63Sdholland } 94126165e63Sdholland if (str[i + 1] != '\0') { 94226165e63Sdholland /* A non-digit caracter, not at the end */ 94326165e63Sdholland return 1; 94426165e63Sdholland } 94526165e63Sdholland if (str[i] == 'G' || str[i] == 'g') { 94626165e63Sdholland val *= 1024; 947da5a563bSmartin *localsizemult = MEG / pm->sectorsize; 94826165e63Sdholland break; 94926165e63Sdholland } 95026165e63Sdholland if (str[i] == 'M' || str[i] == 'm') { 951da5a563bSmartin *localsizemult = MEG / pm->sectorsize; 95226165e63Sdholland break; 95326165e63Sdholland } 95426165e63Sdholland if (str[i] == 'c') { 955da5a563bSmartin *localsizemult = pm->dlcylsize; 95626165e63Sdholland break; 95726165e63Sdholland } 95826165e63Sdholland if (str[i] == 's') { 95926165e63Sdholland *localsizemult = 1; 96026165e63Sdholland break; 96126165e63Sdholland } 96226165e63Sdholland /* not a known unit */ 96326165e63Sdholland return 1; 96426165e63Sdholland } 96526165e63Sdholland *p_val = val * (*localsizemult); 96626165e63Sdholland return 0; 96726165e63Sdholland } 968