Wed Apr 22 23:43:12 2020 UTC ()
Don't depend on common symbol definitions.


(joerg)
diff -r1.57 -r1.58 src/usr.sbin/sysinst/defs.h
diff -r1.23 -r1.24 src/usr.sbin/sysinst/main.c
diff -r1.31 -r1.32 src/usr.sbin/sysinst/mbr.c
diff -r1.4 -r1.5 src/usr.sbin/sysinst/mbr.h

cvs diff -r1.57 -r1.58 src/usr.sbin/sysinst/defs.h (switch to unified diff)

--- src/usr.sbin/sysinst/defs.h 2020/03/16 06:48:17 1.57
+++ src/usr.sbin/sysinst/defs.h 2020/04/22 23:43:12 1.58
@@ -1,960 +1,960 @@ @@ -1,960 +1,960 @@
1/* $NetBSD: defs.h,v 1.57 2020/03/16 06:48:17 martin Exp $ */ 1/* $NetBSD: defs.h,v 1.58 2020/04/22 23:43:12 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright 1997 Piermont Information Systems Inc. 4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Philip A. Nelson for Piermont Information Systems Inc. 7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse 17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
18 * or promote products derived from this software without specific prior 18 * or promote products derived from this software without specific prior
19 * written permission. 19 * written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE. 31 * THE POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35#ifndef _DEFS_H_ 35#ifndef _DEFS_H_
36#define _DEFS_H_ 36#define _DEFS_H_
37 37
38/* defs.h -- definitions for use in the sysinst program. */ 38/* defs.h -- definitions for use in the sysinst program. */
39 39
40/* System includes needed for this. */ 40/* System includes needed for this. */
41#include <sys/queue.h> 41#include <sys/queue.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/disk.h> 43#include <sys/disk.h>
44#include <uuid.h> 44#include <uuid.h>
45 45
46const char *getfslabelname(uint, uint); 46const char *getfslabelname(uint, uint);
47 47
48#include "msg_defs.h" 48#include "msg_defs.h"
49#include "menu_defs.h" 49#include "menu_defs.h"
50#include "partitions.h" 50#include "partitions.h"
51 51
52#define min(a,b) ((a) < (b) ? (a) : (b)) 52#define min(a,b) ((a) < (b) ? (a) : (b))
53#define max(a,b) ((a) > (b) ? (a) : (b)) 53#define max(a,b) ((a) > (b) ? (a) : (b))
54 54
55/* constants */ 55/* constants */
56#define MEG (1024UL * 1024UL) 56#define MEG (1024UL * 1024UL)
57#define GIG (1024UL * MEG) 57#define GIG (1024UL * MEG)
58#define STRSIZE 255 58#define STRSIZE 255
59#define MENUSTRSIZE 80 59#define MENUSTRSIZE 80
60#define SSTRSIZE 30 60#define SSTRSIZE 30
61 61
62/* these are used for different alignment defaults */ 62/* these are used for different alignment defaults */
63#define HUGE_DISK_SIZE (daddr_t)(128 * (GIG / 512)) 63#define HUGE_DISK_SIZE (daddr_t)(128 * (GIG / 512))
64#define TINY_DISK_SIZE (daddr_t)(1800 * (MEG / 512)) 64#define TINY_DISK_SIZE (daddr_t)(1800 * (MEG / 512))
65 65
66/* 66/*
67 * if a system does not have more ram (in MB) than this, swap will be enabled 67 * if a system does not have more ram (in MB) than this, swap will be enabled
68 * very early (as soon as the swap partition has been created) 68 * very early (as soon as the swap partition has been created)
69 */ 69 */
70#define TINY_RAM_SIZE 32 70#define TINY_RAM_SIZE 32
71/* 71/*
72 * if a system has less ram (in MB) than this, we will not create a 72 * if a system has less ram (in MB) than this, we will not create a
73 * tmpfs /tmp by default (to workaround PR misc/54886) 73 * tmpfs /tmp by default (to workaround PR misc/54886)
74 */ 74 */
75#define SMALL_RAM_SIZE 384 75#define SMALL_RAM_SIZE 384
76 76
77/* helper macros to create unique internal error messages */ 77/* helper macros to create unique internal error messages */
78#define STR_NO(STR) #STR 78#define STR_NO(STR) #STR
79#define TO_STR(NO) STR_NO(NO) 79#define TO_STR(NO) STR_NO(NO)
80#define INTERNAL_ERROR __FILE__ ":" TO_STR(__LINE__) ": internal error" 80#define INTERNAL_ERROR __FILE__ ":" TO_STR(__LINE__) ": internal error"
81 81
82/* For run.c: collect() */ 82/* For run.c: collect() */
83#define T_FILE 0 83#define T_FILE 0
84#define T_OUTPUT 1 84#define T_OUTPUT 1
85 85
86/* Some install status/response values */ 86/* Some install status/response values */
87#define SET_OK 0 /* Set extracted */ 87#define SET_OK 0 /* Set extracted */
88#define SET_RETRY 1 /* Retry */ 88#define SET_RETRY 1 /* Retry */
89#define SET_SKIP 2 /* Skip this set */ 89#define SET_SKIP 2 /* Skip this set */
90#define SET_SKIP_GROUP 3 /* Skip this set and rest of group */ 90#define SET_SKIP_GROUP 3 /* Skip this set and rest of group */
91#define SET_ABANDON 4 /* Abandon installation */ 91#define SET_ABANDON 4 /* Abandon installation */
92#define SET_CONTINUE 5 /* Continue (copy from floppy loop) */ 92#define SET_CONTINUE 5 /* Continue (copy from floppy loop) */
93 93
94/* run_prog flags */ 94/* run_prog flags */
95#define RUN_DISPLAY 0x0001 /* Display program output */ 95#define RUN_DISPLAY 0x0001 /* Display program output */
96#define RUN_FATAL 0x0002 /* errors are fatal */ 96#define RUN_FATAL 0x0002 /* errors are fatal */
97#define RUN_CHROOT 0x0004 /* chroot to target disk */ 97#define RUN_CHROOT 0x0004 /* chroot to target disk */
98#define RUN_FULLSCREEN 0x0008 /* fullscreen (use with RUN_DISPLAY) */ 98#define RUN_FULLSCREEN 0x0008 /* fullscreen (use with RUN_DISPLAY) */
99#define RUN_SILENT 0x0010 /* Do not show output */ 99#define RUN_SILENT 0x0010 /* Do not show output */
100#define RUN_ERROR_OK 0x0040 /* Don't wait for error confirmation */ 100#define RUN_ERROR_OK 0x0040 /* Don't wait for error confirmation */
101#define RUN_PROGRESS 0x0080 /* Output is just progess test */ 101#define RUN_PROGRESS 0x0080 /* Output is just progess test */
102#define RUN_NO_CLEAR 0x0100 /* Leave program output after error */ 102#define RUN_NO_CLEAR 0x0100 /* Leave program output after error */
103#define RUN_XFER_DIR 0x0200 /* cd to xfer_dir in child */ 103#define RUN_XFER_DIR 0x0200 /* cd to xfer_dir in child */
104 104
105/* for bsddisklabel.c */ 105/* for bsddisklabel.c */
106enum layout_type { LY_KEEPEXISTING, LY_SETSIZES, LY_USEDEFAULT, LY_USEFULL }; 106enum layout_type { LY_KEEPEXISTING, LY_SETSIZES, LY_USEDEFAULT, LY_USEFULL };
107enum setup_type { SY_NEWRAID, SY_NEWCGD, SY_NEWLVM }; 107enum setup_type { SY_NEWRAID, SY_NEWCGD, SY_NEWLVM };
108 108
109/* Installation sets */ 109/* Installation sets */
110enum { 110enum {
111 SET_NONE, 111 SET_NONE,
112 SET_KERNEL_FIRST, 112 SET_KERNEL_FIRST,
113 SET_KERNEL_1, /* Usually GENERIC */ 113 SET_KERNEL_1, /* Usually GENERIC */
114 SET_KERNEL_2, /* MD kernel... */ 114 SET_KERNEL_2, /* MD kernel... */
115 SET_KERNEL_3, /* MD kernel... */ 115 SET_KERNEL_3, /* MD kernel... */
116 SET_KERNEL_4, /* MD kernel... */ 116 SET_KERNEL_4, /* MD kernel... */
117 SET_KERNEL_5, /* MD kernel... */ 117 SET_KERNEL_5, /* MD kernel... */
118 SET_KERNEL_6, /* MD kernel... */ 118 SET_KERNEL_6, /* MD kernel... */
119 SET_KERNEL_7, /* MD kernel... */ 119 SET_KERNEL_7, /* MD kernel... */
120 SET_KERNEL_8, /* MD kernel... */ 120 SET_KERNEL_8, /* MD kernel... */
121 SET_KERNEL_9, /* MD kernel... */ 121 SET_KERNEL_9, /* MD kernel... */
122 SET_KERNEL_LAST, /* allow 9 kernels */ 122 SET_KERNEL_LAST, /* allow 9 kernels */
123 123
124 /* System sets */ 124 /* System sets */
125 SET_BASE, /* base */ 125 SET_BASE, /* base */
126 SET_ETC, /* /etc */ 126 SET_ETC, /* /etc */
127 SET_COMPILER, /* compiler tools */ 127 SET_COMPILER, /* compiler tools */
128 SET_GAMES, /* text games */ 128 SET_GAMES, /* text games */
129 SET_MAN_PAGES, /* online manual pages */ 129 SET_MAN_PAGES, /* online manual pages */
130 SET_MISC, /* miscellaneuous */ 130 SET_MISC, /* miscellaneuous */
131 SET_MODULES, /* kernel modules */ 131 SET_MODULES, /* kernel modules */
132 SET_RESCUE, /* /rescue recovery tools */ 132 SET_RESCUE, /* /rescue recovery tools */
133 SET_TESTS, /* tests */ 133 SET_TESTS, /* tests */
134 SET_TEXT_TOOLS, /* text processing tools */ 134 SET_TEXT_TOOLS, /* text processing tools */
135 135
136 /* X11 sets */ 136 /* X11 sets */
137 SET_X11_FIRST, 137 SET_X11_FIRST,
138 SET_X11_BASE, /* X11 base and clients */ 138 SET_X11_BASE, /* X11 base and clients */
139 SET_X11_FONTS, /* X11 fonts */ 139 SET_X11_FONTS, /* X11 fonts */
140 SET_X11_SERVERS, /* X11 servers */ 140 SET_X11_SERVERS, /* X11 servers */
141 SET_X11_PROG, /* X11 programming */ 141 SET_X11_PROG, /* X11 programming */
142 SET_X11_ETC, /* X11 config */ 142 SET_X11_ETC, /* X11 config */
143 SET_X11_LAST, 143 SET_X11_LAST,
144 144
145 /* Machine dependent sets */ 145 /* Machine dependent sets */
146 SET_MD_1, /* Machine dependent set */ 146 SET_MD_1, /* Machine dependent set */
147 SET_MD_2, /* Machine dependent set */ 147 SET_MD_2, /* Machine dependent set */
148 SET_MD_3, /* Machine dependent set */ 148 SET_MD_3, /* Machine dependent set */
149 SET_MD_4, /* Machine dependent set */ 149 SET_MD_4, /* Machine dependent set */
150  150
151 /* Source sets */ 151 /* Source sets */
152 SET_SYSSRC, 152 SET_SYSSRC,
153 SET_SRC, 153 SET_SRC,
154 SET_SHARESRC, 154 SET_SHARESRC,
155 SET_GNUSRC, 155 SET_GNUSRC,
156 SET_XSRC, 156 SET_XSRC,
157 157
158 /* Debug sets */ 158 /* Debug sets */
159 SET_DEBUG, 159 SET_DEBUG,
160 SET_X11_DEBUG, 160 SET_X11_DEBUG,
161 161
162 SET_LAST, 162 SET_LAST,
163 SET_GROUP, /* Start of submenu */ 163 SET_GROUP, /* Start of submenu */
164 SET_GROUP_END, /* End of submenu */ 164 SET_GROUP_END, /* End of submenu */
165 SET_PKGSRC, /* pkgsrc, not counted as regular set */ 165 SET_PKGSRC, /* pkgsrc, not counted as regular set */
166}; 166};
167 167
168/* Initialisers to select sets */ 168/* Initialisers to select sets */
169/* All kernels */ 169/* All kernels */
170#define SET_KERNEL SET_KERNEL_1, SET_KERNEL_2, SET_KERNEL_3, SET_KERNEL_4, \ 170#define SET_KERNEL SET_KERNEL_1, SET_KERNEL_2, SET_KERNEL_3, SET_KERNEL_4, \
171 SET_KERNEL_5, SET_KERNEL_6, SET_KERNEL_7, SET_KERNEL_8 171 SET_KERNEL_5, SET_KERNEL_6, SET_KERNEL_7, SET_KERNEL_8
172/* Core system sets */ 172/* Core system sets */
173#define SET_CORE SET_MODULES, SET_BASE, SET_ETC 173#define SET_CORE SET_MODULES, SET_BASE, SET_ETC
174/* All system sets */ 174/* All system sets */
175#define SET_SYSTEM SET_CORE, SET_COMPILER, SET_GAMES, \ 175#define SET_SYSTEM SET_CORE, SET_COMPILER, SET_GAMES, \
176 SET_MAN_PAGES, SET_MISC, SET_RESCUE, \ 176 SET_MAN_PAGES, SET_MISC, SET_RESCUE, \
177 SET_TESTS, SET_TEXT_TOOLS 177 SET_TESTS, SET_TEXT_TOOLS
178/* All X11 sets */ 178/* All X11 sets */
179#define SET_X11_NOSERVERS SET_X11_BASE, SET_X11_FONTS, SET_X11_PROG, SET_X11_ETC 179#define SET_X11_NOSERVERS SET_X11_BASE, SET_X11_FONTS, SET_X11_PROG, SET_X11_ETC
180#define SET_X11 SET_X11_NOSERVERS, SET_X11_SERVERS 180#define SET_X11 SET_X11_NOSERVERS, SET_X11_SERVERS
181 181
182/* All machine dependent sets */ 182/* All machine dependent sets */
183#define SET_MD SET_MD_1, SET_MD_2, SET_MD_3, SET_MD_4 183#define SET_MD SET_MD_1, SET_MD_2, SET_MD_3, SET_MD_4
184 184
185/* All source sets */ 185/* All source sets */
186#define SET_SOURCE SET_SYSSRC, SET_SRC, SET_SHARESRC, SET_GNUSRC, SET_XSRC 186#define SET_SOURCE SET_SYSSRC, SET_SRC, SET_SHARESRC, SET_GNUSRC, SET_XSRC
187 187
188/* All debug sets */ 188/* All debug sets */
189#define SET_DEBUGGING SET_DEBUG, SET_X11_DEBUG 189#define SET_DEBUGGING SET_DEBUG, SET_X11_DEBUG
190 190
191/* Set list flags */ 191/* Set list flags */
192#define SFLAG_MINIMAL 1 192#define SFLAG_MINIMAL 1
193#define SFLAG_NOX 2 193#define SFLAG_NOX 2
194 194
195/* Round up to the next full cylinder size */ 195/* Round up to the next full cylinder size */
196#define NUMSEC(size, sizemult, cylsize) \ 196#define NUMSEC(size, sizemult, cylsize) \
197 ((sizemult) == 1 ? (size) : \ 197 ((sizemult) == 1 ? (size) : \
198 roundup((size) * (sizemult), (cylsize))) 198 roundup((size) * (sizemult), (cylsize)))
199 199
200/* What FS type? */ 200/* What FS type? */
201#define PI_ISBSDFS(PI) (PI_FSTYPE(PI) == FS_BSDLFS || \ 201#define PI_ISBSDFS(PI) (PI_FSTYPE(PI) == FS_BSDLFS || \
202 PI_FSTYPE(PI) == FS_BSDFFS) 202 PI_FSTYPE(PI) == FS_BSDFFS)
203 203
204/* 204/*
205 * We do not offer CDs or floppies as installation target usually. 205 * We do not offer CDs or floppies as installation target usually.
206 * Architectures might want to undefine if they want to allow 206 * Architectures might want to undefine if they want to allow
207 * these devices or redefine if they have unusual CD device names. 207 * these devices or redefine if they have unusual CD device names.
208 * Do not define to empty or an empty string, undefine instead. 208 * Do not define to empty or an empty string, undefine instead.
209 */ 209 */
210#define CD_NAMES "cd*" 210#define CD_NAMES "cd*"
211#define FLOPPY_NAMES "fd*" 211#define FLOPPY_NAMES "fd*"
212 212
213/* Types */ 213/* Types */
214 214
215/* pass a void* argument into a menu and also provide a int return value */ 215/* pass a void* argument into a menu and also provide a int return value */
216typedef struct arg_rv { 216typedef struct arg_rv {
217 void *arg; 217 void *arg;
218 int rv; 218 int rv;
219} arg_rv; 219} arg_rv;
220 220
221/* 221/*
222 * A minimal argument for menus using string replacements 222 * A minimal argument for menus using string replacements
223 */ 223 */
224typedef struct arg_replace { 224typedef struct arg_replace {
225 const char **argv; 225 const char **argv;
226 size_t argc; 226 size_t argc;
227} arg_replace; 227} arg_replace;
228 228
229/* 229/*
230 * pass a parameter array (for string replacements) into a menu and provide 230 * pass a parameter array (for string replacements) into a menu and provide
231 * an integer return value 231 * an integer return value
232 */ 232 */
233typedef struct arg_rep_int { 233typedef struct arg_rep_int {
234 arg_replace args; 234 arg_replace args;
235 int rv; 235 int rv;
236} arg_rep_int; 236} arg_rep_int;
237 237
238typedef struct distinfo { 238typedef struct distinfo {
239 const char *name; 239 const char *name;
240 uint set; 240 uint set;
241 bool force_tgz; /* this set is always in .tgz format */ 241 bool force_tgz; /* this set is always in .tgz format */
242 const char *desc; 242 const char *desc;
243 const char *marker_file; /* set assumed installed if exists */ 243 const char *marker_file; /* set assumed installed if exists */
244} distinfo; 244} distinfo;
245 245
246#define MOUNTLEN 20 246#define MOUNTLEN 20
247 247
248 248
249/* 249/*
250 * A description of a future partition and its usage. 250 * A description of a future partition and its usage.
251 * A list of this is the output of the first stage partition 251 * A list of this is the output of the first stage partition
252 * editor, before it gets transformed into a concrete partition 252 * editor, before it gets transformed into a concrete partition
253 * layout according to the partitioning scheme backend. 253 * layout according to the partitioning scheme backend.
254 */ 254 */
255struct part_usage_info { 255struct part_usage_info {
256 daddr_t size; /* thumb guestimate of size, 256 daddr_t size; /* thumb guestimate of size,
257 * [sec if positive, %-of-ram 257 * [sec if positive, %-of-ram
258 * if TMPFS and negative] 258 * if TMPFS and negative]
259 */ 259 */
260 daddr_t def_size; /* default size */ 260 daddr_t def_size; /* default size */
261 daddr_t limit; /* max size */ 261 daddr_t limit; /* max size */
262 char mount[MOUNTLEN]; /* where will we mount this? */ 262 char mount[MOUNTLEN]; /* where will we mount this? */
263 enum part_type type; /* PT_root/PT_swap/PT_EFI_SYSTEM */ 263 enum part_type type; /* PT_root/PT_swap/PT_EFI_SYSTEM */
264 264
265#define PUIFLAG_EXTEND 1 /* extend this part if free space 265#define PUIFLAG_EXTEND 1 /* extend this part if free space
266 * is available */ 266 * is available */
267#define PUIFLAG_ADD_OUTER 2 /* Add this partition to the outer 267#define PUIFLAG_ADD_OUTER 2 /* Add this partition to the outer
268 * partitions (if available) */ 268 * partitions (if available) */
269#define PUIFLG_IS_OUTER 4 /* this is an existing outer one */ 269#define PUIFLG_IS_OUTER 4 /* this is an existing outer one */
270#define PUIFLG_ADD_INNER 8 /* add outer also to inner */ 270#define PUIFLG_ADD_INNER 8 /* add outer also to inner */
271#define PUIFLG_JUST_MOUNTPOINT 16 /* tmpfs of mfs mountpoints */ 271#define PUIFLG_JUST_MOUNTPOINT 16 /* tmpfs of mfs mountpoints */
272#define PUIFLG_CLONE_PARTS 32 /* clone external partitions */ 272#define PUIFLG_CLONE_PARTS 32 /* clone external partitions */
273 uint flags; 273 uint flags;
274 struct disk_partitions *parts; /* Where does this partition live? 274 struct disk_partitions *parts; /* Where does this partition live?
275 * We currently only support 275 * We currently only support
276 * a single disk, but we plan to 276 * a single disk, but we plan to
277 * extend that. 277 * extend that.
278 * Use pm->parts to access 278 * Use pm->parts to access
279 * the partitions. */ 279 * the partitions. */
280 part_id cur_part_id; /* this may change, but we try to 280 part_id cur_part_id; /* this may change, but we try to
281 * fix it up after all changes */ 281 * fix it up after all changes */
282 daddr_t cur_start; /* may change during editing, just 282 daddr_t cur_start; /* may change during editing, just
283 * used as a unique identifier */ 283 * used as a unique identifier */
284 uint32_t cur_flags; /* PTI_* flags from disk_part_info */ 284 uint32_t cur_flags; /* PTI_* flags from disk_part_info */
285 285
286#define PUIMNT_ASYNC 0x0001 /* mount -o async */ 286#define PUIMNT_ASYNC 0x0001 /* mount -o async */
287#define PUIMNT_NOATIME 0x0002 /* mount -o noatime */ 287#define PUIMNT_NOATIME 0x0002 /* mount -o noatime */
288#define PUIMNT_NODEV 0x0004 /* mount -o nodev */ 288#define PUIMNT_NODEV 0x0004 /* mount -o nodev */
289#define PUIMNT_NODEVMTIME 0x0008 /* mount -o nodevmtime */ 289#define PUIMNT_NODEVMTIME 0x0008 /* mount -o nodevmtime */
290#define PUIMNT_NOEXEC 0x0010 /* mount -o noexec */ 290#define PUIMNT_NOEXEC 0x0010 /* mount -o noexec */
291#define PUIMNT_NOSUID 0x0020 /* mount -o nosuid */ 291#define PUIMNT_NOSUID 0x0020 /* mount -o nosuid */
292#define PUIMNT_LOG 0x0040 /* mount -o log */ 292#define PUIMNT_LOG 0x0040 /* mount -o log */
293#define PUIMNT_NOAUTO 0x0080 /* "noauto" fstab flag */ 293#define PUIMNT_NOAUTO 0x0080 /* "noauto" fstab flag */
294 unsigned int mountflags; /* flags for fstab */ 294 unsigned int mountflags; /* flags for fstab */
295#define PUIINST_NEWFS 0x0001 /* need to 'newfs' partition */ 295#define PUIINST_NEWFS 0x0001 /* need to 'newfs' partition */
296#define PUIINST_MOUNT 0x0002 /* need to mount partition */ 296#define PUIINST_MOUNT 0x0002 /* need to mount partition */
297#define PUIINST_BOOT 0x0004 /* this is a boot partition */ 297#define PUIINST_BOOT 0x0004 /* this is a boot partition */
298 unsigned int instflags; /* installer handling flags */ 298 unsigned int instflags; /* installer handling flags */
299 uint fs_type, fs_version; /* e.g. FS_LFS, or FS_BSDFS, 299 uint fs_type, fs_version; /* e.g. FS_LFS, or FS_BSDFS,
300 * version = 2 for FFSv2 */ 300 * version = 2 for FFSv2 */
301#ifndef NO_CLONES 301#ifndef NO_CLONES
302 /* 302 /*
303 * Only != NULL when PUIFLG_CLONE_PARTS is set, describes the 303 * Only != NULL when PUIFLG_CLONE_PARTS is set, describes the
304 * source partitions to clone here. 304 * source partitions to clone here.
305 */ 305 */
306 struct selected_partitions *clone_src; 306 struct selected_partitions *clone_src;
307 /* 307 /*
308 * If clone_src != NULL, this record corresponds to a single 308 * If clone_src != NULL, this record corresponds to a single
309 * selected source partition, if clone_ndx is a valid index in clone_src 309 * selected source partition, if clone_ndx is a valid index in clone_src
310 * (>= 0 && <= clone_src->num_sel, or all of them if clone_ndx = ~0U. 310 * (>= 0 && <= clone_src->num_sel, or all of them if clone_ndx = ~0U.
311 */ 311 */
312 size_t clone_ndx; 312 size_t clone_ndx;
313#endif 313#endif
314}; 314};
315 315
316/* 316/*
317 * A list of partition suggestions, bundled for editing 317 * A list of partition suggestions, bundled for editing
318 */ 318 */
319struct partition_usage_set { 319struct partition_usage_set {
320 struct disk_partitions *parts; 320 struct disk_partitions *parts;
321 size_t num; 321 size_t num;
322 struct part_usage_info *infos; /* 0 .. num-1 */ 322 struct part_usage_info *infos; /* 0 .. num-1 */
323 daddr_t cur_free_space; /* estimate of free sectors */ 323 daddr_t cur_free_space; /* estimate of free sectors */
324 menu_ent *menu_opts; /* 0 .. num+N */ 324 menu_ent *menu_opts; /* 0 .. num+N */
325 int menu; /* the menu to edit this */ 325 int menu; /* the menu to edit this */
326 bool ok; /* ok to continue (all fit) */ 326 bool ok; /* ok to continue (all fit) */
327}; 327};
328 328
329/* 329/*
330 * A structure we pass around in menus that edit a single partition out 330 * A structure we pass around in menus that edit a single partition out
331 * of a partition_usage_set. 331 * of a partition_usage_set.
332 */ 332 */
333struct single_part_fs_edit { 333struct single_part_fs_edit {
334 struct partition_usage_set *pset; 334 struct partition_usage_set *pset;
335 size_t index, first_custom_attr; 335 size_t index, first_custom_attr;
336 part_id id; 336 part_id id;
337 struct disk_part_info info; /* current partition data */ 337 struct disk_part_info info; /* current partition data */
338 struct part_usage_info *wanted; /* points at our edit data */ 338 struct part_usage_info *wanted; /* points at our edit data */
339 339
340 /* 340 /*
341 * "Backup" of old data, so we can restore previous values 341 * "Backup" of old data, so we can restore previous values
342 * ("undo"). 342 * ("undo").
343 */ 343 */
344 struct part_usage_info old_usage; 344 struct part_usage_info old_usage;
345 struct disk_part_info old_info; 345 struct disk_part_info old_info;
346 346
347 /* menu return value */ 347 /* menu return value */
348 int rv; 348 int rv;
349}; 349};
350 350
351/* 351/*
352 * Description of a full target installation, all partitions and 352 * Description of a full target installation, all partitions and
353 * devices (may be accross several struct pm_devs / disks). 353 * devices (may be accross several struct pm_devs / disks).
354 */ 354 */
355struct install_partition_desc { 355struct install_partition_desc {
356 size_t num; /* how many entries in infos */ 356 size_t num; /* how many entries in infos */
357 struct part_usage_info *infos; /* individual partitions */ 357 struct part_usage_info *infos; /* individual partitions */
358 bool cur_system; /* target is the life system */ 358 bool cur_system; /* target is the life system */
359}; 359};
360 360
361/* variables */ 361/* variables */
362 362
363int debug; /* set by -D option */ 363extern int debug; /* set by -D option */
364 364
365char machine[SSTRSIZE]; 365extern char machine[SSTRSIZE];
366 366
367int ignorerror; 367extern int ignorerror;
368int ttysig_ignore; 368extern int ttysig_ignore;
369pid_t ttysig_forward; 369extern pid_t ttysig_forward;
370uint sizemult; 370extern uint sizemult;
371extern const char *multname; 371extern const char *multname;
372extern const char *err_outofmem; 372extern const char *err_outofmem;
373int partman_go; /* run extended partition manager */ 373extern int partman_go; /* run extended partition manager */
374 374
375/* logging variables */ 375/* logging variables */
376 376
377FILE *logfp; 377extern FILE *logfp;
378FILE *script; 378extern FILE *script;
379 379
380#define MAX_DISKS 15 380#define MAX_DISKS 15
381 381
382daddr_t root_limit; /* BIOS (etc) read limit */ 382extern daddr_t root_limit; /* BIOS (etc) read limit */
383 383
384enum SHRED_T { SHRED_NONE=0, SHRED_ZEROS, SHRED_RANDOM }; 384enum SHRED_T { SHRED_NONE=0, SHRED_ZEROS, SHRED_RANDOM };
385 385
386/* All information that is unique for each drive */ 386/* All information that is unique for each drive */
387SLIST_HEAD(pm_head_t, pm_devs) pm_head; 387extern SLIST_HEAD(pm_head_t, pm_devs) pm_head;
388 388
389struct pm_devs { 389struct pm_devs {
390 /* 390 /*
391 * If device is blocked (e.g. part of a raid) 391 * If device is blocked (e.g. part of a raid)
392 * this is a pointers to the parent dev 392 * this is a pointers to the parent dev
393 */ 393 */
394 void *refdev; 394 void *refdev;
395 395
396 char diskdev[SSTRSIZE]; /* Actual name of the disk. */ 396 char diskdev[SSTRSIZE]; /* Actual name of the disk. */
397 char diskdev_descr[STRSIZE]; /* e.g. IDENTIFY result */ 397 char diskdev_descr[STRSIZE]; /* e.g. IDENTIFY result */
398 398
399 /* 399 /*
400 * What the disk layout should look like. 400 * What the disk layout should look like.
401 */ 401 */
402 struct disk_partitions *parts; 402 struct disk_partitions *parts;
403 403
404 /* 404 /*
405 * The device does not take a MBR, even if we usually use 405 * The device does not take a MBR, even if we usually use
406 * MBR master / disklabel secondary partitioning. 406 * MBR master / disklabel secondary partitioning.
407 * Used e.g. for raid* pseudo-disks. 407 * Used e.g. for raid* pseudo-disks.
408 */ 408 */
409 bool no_mbr; /* userd for raid (etc) */ 409 bool no_mbr; /* userd for raid (etc) */
410 410
411 /* 411 /*
412 * This device can not be partitioned (in any way). 412 * This device can not be partitioned (in any way).
413 * Used for wedges (dk*) or LVM devices. 413 * Used for wedges (dk*) or LVM devices.
414 */ 414 */
415 bool no_part; 415 bool no_part;
416 416
417 /* 417 /*
418 * This is a pseudo-device representing the currently running 418 * This is a pseudo-device representing the currently running
419 * system (i.e. all mounted file systems). 419 * system (i.e. all mounted file systems).
420 */ 420 */
421 bool cur_system; 421 bool cur_system;
422 422
423 /* Actual values for current disk geometry - set by find_disks() or 423 /* Actual values for current disk geometry - set by find_disks() or
424 * md_get_info() 424 * md_get_info()
425 */ 425 */
426 uint sectorsize, dlcyl, dlhead, dlsec, dlcylsize, current_cylsize; 426 uint sectorsize, dlcyl, dlhead, dlsec, dlcylsize, current_cylsize;
427 /* 427 /*
428 * Total size of the disk - in 'sectorsize' units (!) 428 * Total size of the disk - in 'sectorsize' units (!)
429 */ 429 */
430 daddr_t dlsize; /* total number of disk sectors */ 430 daddr_t dlsize; /* total number of disk sectors */
431 431
432 /* Area of disk we can allocate, start and size in sectors. */ 432 /* Area of disk we can allocate, start and size in sectors. */
433 daddr_t ptstart, ptsize; 433 daddr_t ptstart, ptsize;
434 434
435 /* For some bootblocks we need to know the CHS addressable limit */ 435 /* For some bootblocks we need to know the CHS addressable limit */
436 daddr_t max_chs; /* bcyl * bhead * bsec */ 436 daddr_t max_chs; /* bcyl * bhead * bsec */
437 437
438 /* If we have an MBR boot partition, start and size in sectors */ 438 /* If we have an MBR boot partition, start and size in sectors */
439 daddr_t bootstart, bootsize; 439 daddr_t bootstart, bootsize;
440 440
441 /* 441 /*
442 * In extended partitioning: all partitions in parts (number of 442 * In extended partitioning: all partitions in parts (number of
443 * entries is parts->num_part) may actually be mounted (temporarily) 443 * entries is parts->num_part) may actually be mounted (temporarily)
444 * somewhere, e.g. to access a vnd device on them. This list has 444 * somewhere, e.g. to access a vnd device on them. This list has
445 * a pointer to the current mount point (strdup()'d) if mounted, 445 * a pointer to the current mount point (strdup()'d) if mounted,
446 * or NULL if not. 446 * or NULL if not.
447 */ 447 */
448 char **mounted; 448 char **mounted;
449 449
450 bool unsaved; /* Flag indicating to partman that device need saving */ 450 bool unsaved; /* Flag indicating to partman that device need saving */
451 bool found; /* Flag to delete unplugged and unconfigured devices */ 451 bool found; /* Flag to delete unplugged and unconfigured devices */
452 int blocked; /* Device is busy and cannot be changed */ 452 int blocked; /* Device is busy and cannot be changed */
453 453
454 SLIST_ENTRY(pm_devs) l; 454 SLIST_ENTRY(pm_devs) l;
455}; 455};
456struct pm_devs *pm; /* Pointer to current device with which we work */ 456extern struct pm_devs *pm; /* Pointer to current device with which we work */
457struct pm_devs *pm_new; /* Pointer for next allocating device in find_disks() */ 457extern struct pm_devs *pm_new; /* Pointer for next allocating device in find_disks() */
458 458
459/* Generic structure for partman */ 459/* Generic structure for partman */
460struct part_entry { 460struct part_entry {
461 part_id id; 461 part_id id;
462 struct disk_partitions *parts; 462 struct disk_partitions *parts;
463 void *dev_ptr; 463 void *dev_ptr;
464 size_t index; /* e.g. if PM_RAID: this is raids[index] */ 464 size_t index; /* e.g. if PM_RAID: this is raids[index] */
465 int dev_ptr_delta; 465 int dev_ptr_delta;
466 char fullname[SSTRSIZE]; 466 char fullname[SSTRSIZE];
467 enum {PM_DISK=1, PM_PART, PM_SPEC, 467 enum {PM_DISK=1, PM_PART, PM_SPEC,
468 PM_RAID, PM_CGD, PM_VND, PM_LVM, PM_LVMLV} type; 468 PM_RAID, PM_CGD, PM_VND, PM_LVM, PM_LVMLV} type;
469}; 469};
470 470
471/* Relative file name for storing a distribution. */ 471/* Relative file name for storing a distribution. */
472char xfer_dir[STRSIZE]; 472extern char xfer_dir[STRSIZE];
473int clean_xfer_dir; 473extern int clean_xfer_dir;
474 474
475#if !defined(SYSINST_FTP_HOST) 475#if !defined(SYSINST_FTP_HOST)
476#define SYSINST_FTP_HOST "ftp.NetBSD.org" 476#define SYSINST_FTP_HOST "ftp.NetBSD.org"
477#endif 477#endif
478 478
479#if !defined(SYSINST_HTTP_HOST) 479#if !defined(SYSINST_HTTP_HOST)
480#define SYSINST_HTTP_HOST "cdn.NetBSD.org" 480#define SYSINST_HTTP_HOST "cdn.NetBSD.org"
481#endif 481#endif
482 482
483#if !defined(SYSINST_FTP_DIR) 483#if !defined(SYSINST_FTP_DIR)
484#if defined(NETBSD_OFFICIAL_RELEASE) 484#if defined(NETBSD_OFFICIAL_RELEASE)
485#define SYSINST_FTP_DIR "pub/NetBSD/NetBSD-" REL 485#define SYSINST_FTP_DIR "pub/NetBSD/NetBSD-" REL
486#elif defined(REL_PATH) 486#elif defined(REL_PATH)
487#define SYSINST_FTP_DIR "pub/NetBSD-daily/" REL_PATH "/latest" 487#define SYSINST_FTP_DIR "pub/NetBSD-daily/" REL_PATH "/latest"
488#else 488#else
489#define SYSINST_FTP_DIR "pub/NetBSD/NetBSD-" REL 489#define SYSINST_FTP_DIR "pub/NetBSD/NetBSD-" REL
490#endif 490#endif
491#endif 491#endif
492 492
493#if !defined(ARCH_SUBDIR) 493#if !defined(ARCH_SUBDIR)
494#define ARCH_SUBDIR MACH 494#define ARCH_SUBDIR MACH
495#endif 495#endif
496#if !defined(PKG_ARCH_SUBDIR) 496#if !defined(PKG_ARCH_SUBDIR)
497#define PKG_ARCH_SUBDIR MACH 497#define PKG_ARCH_SUBDIR MACH
498#endif 498#endif
499 499
500#if !defined(SYSINST_PKG_HOST) 500#if !defined(SYSINST_PKG_HOST)
501#define SYSINST_PKG_HOST "ftp.NetBSD.org" 501#define SYSINST_PKG_HOST "ftp.NetBSD.org"
502#endif 502#endif
503#if !defined(SYSINST_PKG_HTTP_HOST) 503#if !defined(SYSINST_PKG_HTTP_HOST)
504#define SYSINST_PKG_HTTP_HOST "cdn.NetBSD.org" 504#define SYSINST_PKG_HTTP_HOST "cdn.NetBSD.org"
505#endif 505#endif
506 506
507#if !defined(SYSINST_PKG_DIR) 507#if !defined(SYSINST_PKG_DIR)
508#define SYSINST_PKG_DIR "pub/pkgsrc/packages/NetBSD" 508#define SYSINST_PKG_DIR "pub/pkgsrc/packages/NetBSD"
509#endif 509#endif
510 510
511#if !defined(PKG_SUBDIR) 511#if !defined(PKG_SUBDIR)
512#define PKG_SUBDIR REL 512#define PKG_SUBDIR REL
513#endif 513#endif
514 514
515#if !defined(SYSINST_PKGSRC_HOST) 515#if !defined(SYSINST_PKGSRC_HOST)
516#define SYSINST_PKGSRC_HOST SYSINST_PKG_HOST 516#define SYSINST_PKGSRC_HOST SYSINST_PKG_HOST
517#endif 517#endif
518#if !defined(SYSINST_PKGSRC_HTTP_HOST) 518#if !defined(SYSINST_PKGSRC_HTTP_HOST)
519#define SYSINST_PKGSRC_HTTP_HOST SYSINST_PKG_HTTP_HOST 519#define SYSINST_PKGSRC_HTTP_HOST SYSINST_PKG_HTTP_HOST
520#endif 520#endif
521 521
522#ifndef SETS_TAR_SUFF 522#ifndef SETS_TAR_SUFF
523#define SETS_TAR_SUFF "tgz" 523#define SETS_TAR_SUFF "tgz"
524#endif 524#endif
525 525
526#ifdef USING_PAXASTAR 526#ifdef USING_PAXASTAR
527#define TAR_EXTRACT_FLAGS "-xhepf" 527#define TAR_EXTRACT_FLAGS "-xhepf"
528#else 528#else
529#define TAR_EXTRACT_FLAGS "-xpf" 529#define TAR_EXTRACT_FLAGS "-xpf"
530#endif 530#endif
531 531
532/* Abs. path we extract binary sets from */ 532/* Abs. path we extract binary sets from */
533char ext_dir_bin[STRSIZE]; 533extern char ext_dir_bin[STRSIZE];
534 534
535/* Abs. path we extract source sets from */ 535/* Abs. path we extract source sets from */
536char ext_dir_src[STRSIZE]; 536extern char ext_dir_src[STRSIZE];
537 537
538/* Abs. path we extract pkgsrc from */ 538/* Abs. path we extract pkgsrc from */
539char ext_dir_pkgsrc[STRSIZE]; 539extern char ext_dir_pkgsrc[STRSIZE];
540 540
541/* Place we look for binary sets in all fs types */ 541/* Place we look for binary sets in all fs types */
542char set_dir_bin[STRSIZE]; 542extern char set_dir_bin[STRSIZE];
543 543
544/* Place we look for source sets in all fs types */ 544/* Place we look for source sets in all fs types */
545char set_dir_src[STRSIZE]; 545extern char set_dir_src[STRSIZE];
546 546
547/* Place we look for pkgs in all fs types */ 547/* Place we look for pkgs in all fs types */
548char pkg_dir[STRSIZE]; 548extern char pkg_dir[STRSIZE];
549 549
550/* Place we look for pkgsrc in all fs types */ 550/* Place we look for pkgsrc in all fs types */
551char pkgsrc_dir[STRSIZE]; 551extern char pkgsrc_dir[STRSIZE];
552 552
553/* User shell */ 553/* User shell */
554const char *ushell; 554extern const char *ushell;
555 555
556#define XFER_FTP 0 556#define XFER_FTP 0
557#define XFER_HTTP 1 557#define XFER_HTTP 1
558#define XFER_MAX XFER_HTTP 558#define XFER_MAX XFER_HTTP
559 559
560struct ftpinfo { 560struct ftpinfo {
561 char xfer_host[XFER_MAX+1][STRSIZE]; 561 char xfer_host[XFER_MAX+1][STRSIZE];
562 char dir[STRSIZE] ; 562 char dir[STRSIZE] ;
563 char user[SSTRSIZE]; 563 char user[SSTRSIZE];
564 char pass[STRSIZE]; 564 char pass[STRSIZE];
565 char proxy[STRSIZE]; 565 char proxy[STRSIZE];
566 unsigned int xfer; /* XFER_FTP for "ftp" or XFER_HTTP for "http" */ 566 unsigned int xfer; /* XFER_FTP for "ftp" or XFER_HTTP for "http" */
567}; 567};
568 568
569/* use the same struct for sets ftp and to build pkgpath */ 569/* use the same struct for sets ftp and to build pkgpath */
570struct ftpinfo ftp, pkg, pkgsrc; 570extern struct ftpinfo ftp, pkg, pkgsrc;
571 571
572int (*fetch_fn)(const char *); 572extern int (*fetch_fn)(const char *);
573char nfs_host[STRSIZE]; 573extern char nfs_host[STRSIZE];
574char nfs_dir[STRSIZE]; 574extern char nfs_dir[STRSIZE];
575 575
576char cdrom_dev[SSTRSIZE]; /* Typically "cd0a" */ 576extern char cdrom_dev[SSTRSIZE]; /* Typically "cd0a" */
577char fd_dev[SSTRSIZE]; /* Typically "/dev/fd0a" */ 577extern char fd_dev[SSTRSIZE]; /* Typically "/dev/fd0a" */
578const char *fd_type; /* "msdos", "ffs" or maybe "ados" */ 578extern const char *fd_type; /* "msdos", "ffs" or maybe "ados" */
579 579
580char localfs_dev[SSTRSIZE]; 580extern char localfs_dev[SSTRSIZE];
581char localfs_fs[SSTRSIZE]; 581extern char localfs_fs[SSTRSIZE];
582char localfs_dir[STRSIZE]; 582extern char localfs_dir[STRSIZE];
583 583
584char targetroot_mnt[SSTRSIZE]; 584extern char targetroot_mnt[SSTRSIZE];
585 585
586int mnt2_mounted; 586extern int mnt2_mounted;
587 587
588char dist_postfix[SSTRSIZE]; 588extern char dist_postfix[SSTRSIZE];
589char dist_tgz_postfix[SSTRSIZE]; 589extern char dist_tgz_postfix[SSTRSIZE];
590 590
591/* needed prototypes */ 591/* needed prototypes */
592void set_menu_numopts(int, int); 592void set_menu_numopts(int, int);
593void remove_color_options(void); 593void remove_color_options(void);
594void remove_raid_options(void); 594void remove_raid_options(void);
595void remove_lvm_options(void); 595void remove_lvm_options(void);
596void remove_cgd_options(void); 596void remove_cgd_options(void);
597 597
598/* Machine dependent functions .... */ 598/* Machine dependent functions .... */
599void md_init(void); 599void md_init(void);
600void md_init_set_status(int); /* SFLAG_foo */ 600void md_init_set_status(int); /* SFLAG_foo */
601 601
602 /* MD functions if user selects install - in order called */ 602 /* MD functions if user selects install - in order called */
603bool md_get_info(struct install_partition_desc*); 603bool md_get_info(struct install_partition_desc*);
604bool md_make_bsd_partitions(struct install_partition_desc*); 604bool md_make_bsd_partitions(struct install_partition_desc*);
605bool md_check_partitions(struct install_partition_desc*); 605bool md_check_partitions(struct install_partition_desc*);
606#ifdef HAVE_GPT 606#ifdef HAVE_GPT
607/* 607/*
608 * New GPT partitions have been written, update bootloader or remember 608 * New GPT partitions have been written, update bootloader or remember
609 * data untill needed in md_post_newfs 609 * data untill needed in md_post_newfs
610 */ 610 */
611bool md_gpt_post_write(struct disk_partitions*, part_id root_id, 611bool md_gpt_post_write(struct disk_partitions*, part_id root_id,
612 bool root_is_new, part_id efi_id, bool efi_is_new); 612 bool root_is_new, part_id efi_id, bool efi_is_new);
613#endif 613#endif
614/* 614/*
615 * md_pre_disklabel and md_post_disklabel may be called 615 * md_pre_disklabel and md_post_disklabel may be called
616 * multiple times, for each affected device, with the 616 * multiple times, for each affected device, with the
617 * "inner" partitions pointer of the relevant partitions 617 * "inner" partitions pointer of the relevant partitions
618 * passed. 618 * passed.
619 */ 619 */
620bool md_pre_disklabel(struct install_partition_desc*, struct disk_partitions*); 620bool md_pre_disklabel(struct install_partition_desc*, struct disk_partitions*);
621bool md_post_disklabel(struct install_partition_desc*, struct disk_partitions*); 621bool md_post_disklabel(struct install_partition_desc*, struct disk_partitions*);
622int md_pre_mount(struct install_partition_desc*, size_t); 622int md_pre_mount(struct install_partition_desc*, size_t);
623int md_post_newfs(struct install_partition_desc*); 623int md_post_newfs(struct install_partition_desc*);
624int md_post_extract(struct install_partition_desc*); 624int md_post_extract(struct install_partition_desc*);
625void md_cleanup_install(struct install_partition_desc*); 625void md_cleanup_install(struct install_partition_desc*);
626 626
627 /* MD functions if user selects upgrade - in order called */ 627 /* MD functions if user selects upgrade - in order called */
628int md_pre_update(struct install_partition_desc*); 628int md_pre_update(struct install_partition_desc*);
629int md_update(struct install_partition_desc*); 629int md_update(struct install_partition_desc*);
630/* Also calls md_post_extract() */ 630/* Also calls md_post_extract() */
631 631
632/* from main.c */ 632/* from main.c */
633void toplevel(void); 633void toplevel(void);
634 634
635/* from disks.c */ 635/* from disks.c */
636bool get_default_cdrom(char *, size_t); 636bool get_default_cdrom(char *, size_t);
637int find_disks(const char *, bool); 637int find_disks(const char *, bool);
638bool enumerate_disks(void *state,bool (*func)(void *state, const char *dev)); 638bool enumerate_disks(void *state,bool (*func)(void *state, const char *dev));
639bool is_cdrom_device(const char *dev, bool as_target); 639bool is_cdrom_device(const char *dev, bool as_target);
640bool is_bootable_device(const char *dev); 640bool is_bootable_device(const char *dev);
641bool is_partitionable_device(const char *dev); 641bool is_partitionable_device(const char *dev);
642bool convert_scheme(struct pm_devs *p, bool is_boot_drive, const char **err_msg); 642bool convert_scheme(struct pm_devs *p, bool is_boot_drive, const char **err_msg);
643 643
644#ifndef NO_CLONES 644#ifndef NO_CLONES
645/* a single partition selected for cloning (etc) */ 645/* a single partition selected for cloning (etc) */
646struct selected_partition { 646struct selected_partition {
647 struct disk_partitions *parts; 647 struct disk_partitions *parts;
648 part_id id; 648 part_id id;
649}; 649};
650struct selected_partitions { 650struct selected_partitions {
651 struct selected_partition *selection; 651 struct selected_partition *selection;
652 size_t num_sel; 652 size_t num_sel;
653 bool with_data; /* partitions and their data selected */ 653 bool with_data; /* partitions and their data selected */
654 bool free_parts; /* caller should free parts */ 654 bool free_parts; /* caller should free parts */
655}; 655};
656bool select_partitions(struct selected_partitions *res, 656bool select_partitions(struct selected_partitions *res,
657 const struct disk_partitions *ignore); 657 const struct disk_partitions *ignore);
658daddr_t selected_parts_size(struct selected_partitions *); 658daddr_t selected_parts_size(struct selected_partitions *);
659void free_selected_partitions(struct selected_partitions *); 659void free_selected_partitions(struct selected_partitions *);
660 660
661struct clone_target_menu_data { 661struct clone_target_menu_data {
662 struct partition_usage_set usage; 662 struct partition_usage_set usage;
663 int res; 663 int res;
664}; 664};
665 665
666int clone_target_select(menudesc *m, void *arg); 666int clone_target_select(menudesc *m, void *arg);
667bool clone_partition_data(struct disk_partitions *dest_parts, part_id did, 667bool clone_partition_data(struct disk_partitions *dest_parts, part_id did,
668 struct disk_partitions *src_parts, part_id sid); 668 struct disk_partitions *src_parts, part_id sid);
669#endif 669#endif
670 670
671struct menudesc; 671struct menudesc;
672void disp_cur_fspart(int, int); 672void disp_cur_fspart(int, int);
673int make_filesystems(struct install_partition_desc *); 673int make_filesystems(struct install_partition_desc *);
674int make_fstab(struct install_partition_desc *); 674int make_fstab(struct install_partition_desc *);
675int mount_disks(struct install_partition_desc *); 675int mount_disks(struct install_partition_desc *);
676int set_swap_if_low_ram(struct install_partition_desc *); 676int set_swap_if_low_ram(struct install_partition_desc *);
677int set_swap(struct install_partition_desc *); 677int set_swap(struct install_partition_desc *);
678int check_swap(const char *, int); 678int check_swap(const char *, int);
679char *bootxx_name(struct install_partition_desc *); 679char *bootxx_name(struct install_partition_desc *);
680int get_dkwedges(struct dkwedge_info **, const char *); 680int get_dkwedges(struct dkwedge_info **, const char *);
681 681
682/* from disks_lfs.c */ 682/* from disks_lfs.c */
683int fs_is_lfs(void *); 683int fs_is_lfs(void *);
684 684
685/* from label.c */ 685/* from label.c */
686/* 686/*
687 * Bits valid for "flags" in get_last_mounted. 687 * Bits valid for "flags" in get_last_mounted.
688 * Currently we return the real last mount from FFS, the volume label 688 * Currently we return the real last mount from FFS, the volume label
689 * from FAT32, and nothing otherwise. The NTFS support is currently 689 * from FAT32, and nothing otherwise. The NTFS support is currently
690 * restricted to verify the partition has an NTFS (as some partitioning 690 * restricted to verify the partition has an NTFS (as some partitioning
691 * schemes do not tell NTFS from FAT). 691 * schemes do not tell NTFS from FAT).
692 */ 692 */
693#define GLM_LIKELY_FFS 1U 693#define GLM_LIKELY_FFS 1U
694#define GLM_MAYBE_FAT32 2U 694#define GLM_MAYBE_FAT32 2U
695#define GLM_MAYBE_NTFS 4U 695#define GLM_MAYBE_NTFS 4U
696/* 696/*
697 * possible fs_sub_types are currently: 697 * possible fs_sub_types are currently:
698 * FS_BSDFFS: 698 * FS_BSDFFS:
699 * 0 unknown 699 * 0 unknown
700 * 1 FFSv1 700 * 1 FFSv1
701 * 2 FFSv2 701 * 2 FFSv2
702 * FS_MSDOS: 702 * FS_MSDOS:
703 * 0 unknown 703 * 0 unknown
704 * else MBR_PTYPE_FAT* for the current FAT variant 704 * else MBR_PTYPE_FAT* for the current FAT variant
705 * FS_NTFS: 705 * FS_NTFS:
706 * 0 unknown 706 * 0 unknown
707 * else MBR_PTYPE_NTFS (if valid NTFS was found) 707 * else MBR_PTYPE_NTFS (if valid NTFS was found)
708 * 708 *
709 * The fs_type and fs_sub_type pointers may be NULL. 709 * The fs_type and fs_sub_type pointers may be NULL.
710 */ 710 */
711const char *get_last_mounted(int fd, daddr_t offset, uint *fs_type, 711const char *get_last_mounted(int fd, daddr_t offset, uint *fs_type,
712 uint *fs_sub_type, uint flags); 712 uint *fs_sub_type, uint flags);
713void canonicalize_last_mounted(char*); 713void canonicalize_last_mounted(char*);
714int edit_and_check_label(struct pm_devs *p, struct partition_usage_set *pset, bool install); 714int edit_and_check_label(struct pm_devs *p, struct partition_usage_set *pset, bool install);
715int edit_ptn(menudesc *, void *); 715int edit_ptn(menudesc *, void *);
716int checkoverlap(struct disk_partitions *parts); 716int checkoverlap(struct disk_partitions *parts);
717daddr_t getpartsize(struct disk_partitions *parts, daddr_t partstart, 717daddr_t getpartsize(struct disk_partitions *parts, daddr_t partstart,
718 daddr_t defpartsize); 718 daddr_t defpartsize);
719daddr_t getpartoff(struct disk_partitions *parts, daddr_t defpartstart); 719daddr_t getpartoff(struct disk_partitions *parts, daddr_t defpartstart);
720 720
721/* from install.c */ 721/* from install.c */
722void do_install(void); 722void do_install(void);
723 723
724/* from factor.c */ 724/* from factor.c */
725void factor(long, long *, int, int *); 725void factor(long, long *, int, int *);
726 726
727/* from fdisk.c */ 727/* from fdisk.c */
728void get_disk_info(char *); 728void get_disk_info(char *);
729void set_disk_info(char *); 729void set_disk_info(char *);
730 730
731/* from geom.c */ 731/* from geom.c */
732bool disk_ioctl(const char *, unsigned long, void *); 732bool disk_ioctl(const char *, unsigned long, void *);
733bool get_wedge_list(const char *, struct dkwedge_list *); 733bool get_wedge_list(const char *, struct dkwedge_list *);
734bool get_wedge_info(const char *, struct dkwedge_info *); 734bool get_wedge_info(const char *, struct dkwedge_info *);
735bool get_disk_geom(const char *, struct disk_geom *); 735bool get_disk_geom(const char *, struct disk_geom *);
736bool get_label_geom(const char *, struct disklabel *); 736bool get_label_geom(const char *, struct disklabel *);
737 737
738/* from net.c */ 738/* from net.c */
739extern int network_up; 739extern int network_up;
740extern char net_namesvr[STRSIZE]; 740extern char net_namesvr[STRSIZE];
741int get_via_ftp(unsigned int); 741int get_via_ftp(unsigned int);
742int get_via_nfs(void); 742int get_via_nfs(void);
743int config_network(void); 743int config_network(void);
744void mnt_net_config(void); 744void mnt_net_config(void);
745void make_url(char *, struct ftpinfo *, const char *); 745void make_url(char *, struct ftpinfo *, const char *);
746int get_pkgsrc(void); 746int get_pkgsrc(void);
747const char *url_proto(unsigned int); 747const char *url_proto(unsigned int);
748 748
749/* From run.c */ 749/* From run.c */
750int collect(int, char **, const char *, ...) __printflike(3, 4); 750int collect(int, char **, const char *, ...) __printflike(3, 4);
751int run_program(int, const char *, ...) __printflike(2, 3); 751int run_program(int, const char *, ...) __printflike(2, 3);
752void do_logging(void); 752void do_logging(void);
753int do_system(const char *); 753int do_system(const char *);
754 754
755/* from upgrade.c */ 755/* from upgrade.c */
756void do_upgrade(void); 756void do_upgrade(void);
757void do_reinstall_sets(void); 757void do_reinstall_sets(void);
758void restore_etc(void); 758void restore_etc(void);
759 759
760/* from part_edit.c */ 760/* from part_edit.c */
761int err_msg_win(const char*); 761int err_msg_win(const char*);
762const struct disk_partitioning_scheme *select_part_scheme(struct pm_devs *dev, 762const struct disk_partitioning_scheme *select_part_scheme(struct pm_devs *dev,
763 const struct disk_partitioning_scheme *skip, bool bootable, 763 const struct disk_partitioning_scheme *skip, bool bootable,
764 const char *title); 764 const char *title);
765bool edit_outer_parts(struct disk_partitions*); 765bool edit_outer_parts(struct disk_partitions*);
766bool parts_use_wholedisk(struct disk_partitions*, 766bool parts_use_wholedisk(struct disk_partitions*,
767 size_t add_ext_parts, const struct disk_part_info *ext_parts); 767 size_t add_ext_parts, const struct disk_part_info *ext_parts);
768 768
769/* 769/*
770 * Machine dependent partitioning function, only used when 770 * Machine dependent partitioning function, only used when
771 * innern/outer partitioning schemes are in use - this sets 771 * innern/outer partitioning schemes are in use - this sets
772 * up the outer scheme for maximum NetBSD usage. 772 * up the outer scheme for maximum NetBSD usage.
773 */ 773 */
774bool md_parts_use_wholedisk(struct disk_partitions*); 774bool md_parts_use_wholedisk(struct disk_partitions*);
775 775
776/* from util.c */ 776/* from util.c */
777bool root_is_read_only(void); 777bool root_is_read_only(void);
778void get_ptn_alignment(const struct disk_partitions *parts, daddr_t *align, daddr_t *p0off); 778void get_ptn_alignment(const struct disk_partitions *parts, daddr_t *align, daddr_t *p0off);
779struct disk_partitions *get_inner_parts(struct disk_partitions *parts); 779struct disk_partitions *get_inner_parts(struct disk_partitions *parts);
780char* str_arg_subst(const char *, size_t, const char **); 780char* str_arg_subst(const char *, size_t, const char **);
781void msg_display_subst(const char *, size_t, ...); 781void msg_display_subst(const char *, size_t, ...);
782void msg_display_add_subst(const char *, size_t, ...); 782void msg_display_add_subst(const char *, size_t, ...);
783int ask_yesno(const char *); 783int ask_yesno(const char *);
784int ask_noyes(const char *); 784int ask_noyes(const char *);
785void hit_enter_to_continue(const char *msg, const char *title); 785void hit_enter_to_continue(const char *msg, const char *title);
786/* 786/*
787 * return value: 787 * return value:
788 * 0 -> abort 788 * 0 -> abort
789 * 1 -> re-edit 789 * 1 -> re-edit
790 * 2 -> continue installation 790 * 2 -> continue installation
791*/ 791*/
792int ask_reedit(const struct disk_partitions *); 792int ask_reedit(const struct disk_partitions *);
793int dir_exists_p(const char *); 793int dir_exists_p(const char *);
794int file_exists_p(const char *); 794int file_exists_p(const char *);
795int file_mode_match(const char *, unsigned int); 795int file_mode_match(const char *, unsigned int);
796uint64_t get_ramsize(void); /* in MB! */ 796uint64_t get_ramsize(void); /* in MB! */
797void ask_sizemult(int); 797void ask_sizemult(int);
798void run_makedev(void); 798void run_makedev(void);
799int boot_media_still_needed(void); 799int boot_media_still_needed(void);
800int get_via_floppy(void); 800int get_via_floppy(void);
801int get_via_cdrom(void); 801int get_via_cdrom(void);
802int get_via_localfs(void); 802int get_via_localfs(void);
803int get_via_localdir(void); 803int get_via_localdir(void);
804void show_cur_distsets(void); 804void show_cur_distsets(void);
805void make_ramdisk_dir(const char *); 805void make_ramdisk_dir(const char *);
806void set_kernel_set(unsigned int); 806void set_kernel_set(unsigned int);
807void set_noextract_set(unsigned int); 807void set_noextract_set(unsigned int);
808unsigned int get_kernel_set(void); 808unsigned int get_kernel_set(void);
809unsigned int set_X11_selected(void); 809unsigned int set_X11_selected(void);
810int get_and_unpack_sets(int, msg, msg, msg); 810int get_and_unpack_sets(int, msg, msg, msg);
811int sanity_check(void); 811int sanity_check(void);
812int set_timezone(void); 812int set_timezone(void);
813void scripting_fprintf(FILE *, const char *, ...) __printflike(2, 3); 813void scripting_fprintf(FILE *, const char *, ...) __printflike(2, 3);
814void scripting_vfprintf(FILE *, const char *, va_list) __printflike(2, 0); 814void scripting_vfprintf(FILE *, const char *, va_list) __printflike(2, 0);
815void add_rc_conf(const char *, ...) __printflike(1, 2); 815void add_rc_conf(const char *, ...) __printflike(1, 2);
816int del_rc_conf(const char *); 816int del_rc_conf(const char *);
817void add_sysctl_conf(const char *, ...) __printflike(1, 2); 817void add_sysctl_conf(const char *, ...) __printflike(1, 2);
818void enable_rc_conf(void); 818void enable_rc_conf(void);
819void set_sizemult(daddr_t, uint bps); 819void set_sizemult(daddr_t, uint bps);
820void set_default_sizemult(const char *disk, daddr_t unit, uint bps); 820void set_default_sizemult(const char *disk, daddr_t unit, uint bps);
821int check_lfs_progs(void); 821int check_lfs_progs(void);
822void init_set_status(int); 822void init_set_status(int);
823void customise_sets(void); 823void customise_sets(void);
824void umount_mnt2(void); 824void umount_mnt2(void);
825int set_is_source(const char *); 825int set_is_source(const char *);
826const char *set_dir_for_set(const char *); 826const char *set_dir_for_set(const char *);
827const char *ext_dir_for_set(const char *); 827const char *ext_dir_for_set(const char *);
828void replace(const char *, const char *, ...) __printflike(2, 3); 828void replace(const char *, const char *, ...) __printflike(2, 3);
829void get_tz_default(void); 829void get_tz_default(void);
830distinfo* get_set_distinfo(int); 830distinfo* get_set_distinfo(int);
831int extract_file(distinfo *, int); 831int extract_file(distinfo *, int);
832int extract_file_to(distinfo *dist, int update, const char *dest_dir, 832int extract_file_to(distinfo *dist, int update, const char *dest_dir,
833 const char *extr_pattern, bool do_stats); 833 const char *extr_pattern, bool do_stats);
834void do_coloring (unsigned int, unsigned int); 834void do_coloring (unsigned int, unsigned int);
835int set_menu_select(menudesc *, void *); 835int set_menu_select(menudesc *, void *);
836const char *safectime(time_t *); 836const char *safectime(time_t *);
837bool use_tgz_for_set(const char*); 837bool use_tgz_for_set(const char*);
838const char *set_postfix(const char*); 838const char *set_postfix(const char*);
839bool usage_set_from_parts(struct partition_usage_set*, 839bool usage_set_from_parts(struct partition_usage_set*,
840 struct disk_partitions*); 840 struct disk_partitions*);
841void free_usage_set(struct partition_usage_set*); 841void free_usage_set(struct partition_usage_set*);
842bool install_desc_from_parts(struct install_partition_desc *, 842bool install_desc_from_parts(struct install_partition_desc *,
843 struct disk_partitions*); 843 struct disk_partitions*);
844void free_install_desc(struct install_partition_desc*); 844void free_install_desc(struct install_partition_desc*);
845bool may_swap_if_not_sdmmc(const char*); 845bool may_swap_if_not_sdmmc(const char*);
846 846
847/* from target.c */ 847/* from target.c */
848#if defined(DEBUG) || defined(DEBUG_ROOT) 848#if defined(DEBUG) || defined(DEBUG_ROOT)
849void backtowin(void); 849void backtowin(void);
850#endif 850#endif
851bool is_root_part_mount(const char *); 851bool is_root_part_mount(const char *);
852const char *concat_paths(const char *, const char *); 852const char *concat_paths(const char *, const char *);
853const char *target_expand(const char *); 853const char *target_expand(const char *);
854bool needs_expanding(const char *, size_t); 854bool needs_expanding(const char *, size_t);
855void make_target_dir(const char *); 855void make_target_dir(const char *);
856void append_to_target_file(const char *, const char *); 856void append_to_target_file(const char *, const char *);
857void echo_to_target_file(const char *, const char *); 857void echo_to_target_file(const char *, const char *);
858void trunc_target_file(const char *); 858void trunc_target_file(const char *);
859const char *target_prefix(void); 859const char *target_prefix(void);
860int target_chdir(const char *); 860int target_chdir(const char *);
861void target_chdir_or_die(const char *); 861void target_chdir_or_die(const char *);
862int target_already_root(void); 862int target_already_root(void);
863FILE *target_fopen(const char *, const char *); 863FILE *target_fopen(const char *, const char *);
864int target_collect_file(int, char **, const char *); 864int target_collect_file(int, char **, const char *);
865int is_active_rootpart(const char *, int); 865int is_active_rootpart(const char *, int);
866int cp_to_target(const char *, const char *); 866int cp_to_target(const char *, const char *);
867void dup_file_into_target(const char *); 867void dup_file_into_target(const char *);
868void mv_within_target_or_die(const char *, const char *); 868void mv_within_target_or_die(const char *, const char *);
869int cp_within_target(const char *, const char *, int); 869int cp_within_target(const char *, const char *, int);
870int target_mount(const char *, const char *, const char *); 870int target_mount(const char *, const char *, const char *);
871int target_mount_do(const char *, const char *, const char *); 871int target_mount_do(const char *, const char *, const char *);
872int target_test(unsigned int, const char *); 872int target_test(unsigned int, const char *);
873int target_dir_exists_p(const char *); 873int target_dir_exists_p(const char *);
874int target_file_exists_p(const char *); 874int target_file_exists_p(const char *);
875int target_symlink_exists_p(const char *); 875int target_symlink_exists_p(const char *);
876void unwind_mounts(void); 876void unwind_mounts(void);
877int target_mounted(void); 877int target_mounted(void);
878void umount_root(void); 878void umount_root(void);
879 879
880/* from partman.c */ 880/* from partman.c */
881#ifndef NO_PARTMAN 881#ifndef NO_PARTMAN
882int partman(void); 882int partman(void);
883int pm_getrefdev(struct pm_devs *); 883int pm_getrefdev(struct pm_devs *);
884void update_wedges(const char *); 884void update_wedges(const char *);
885void pm_destroy_all(void); 885void pm_destroy_all(void);
886#else 886#else
887static inline int partman(void) { return -1; } 887static inline int partman(void) { return -1; }
888static inline int pm_getrefdev(struct pm_devs *x __unused) { return -1; } 888static inline int pm_getrefdev(struct pm_devs *x __unused) { return -1; }
889#define update_wedges(x) __nothing 889#define update_wedges(x) __nothing
890#endif 890#endif
891void pmdiskentry_enable(menudesc*, struct part_entry *); 891void pmdiskentry_enable(menudesc*, struct part_entry *);
892int pm_partusage(struct pm_devs *, int, int); 892int pm_partusage(struct pm_devs *, int, int);
893void pm_setfstype(struct pm_devs *, part_id, int, int); 893void pm_setfstype(struct pm_devs *, part_id, int, int);
894void pm_set_lvmpv(struct pm_devs *, part_id, bool); 894void pm_set_lvmpv(struct pm_devs *, part_id, bool);
895bool pm_is_lvmpv(struct pm_devs *, part_id, const struct disk_part_info*); 895bool pm_is_lvmpv(struct pm_devs *, part_id, const struct disk_part_info*);
896int pm_editpart(int); 896int pm_editpart(int);
897void pm_rename(struct pm_devs *); 897void pm_rename(struct pm_devs *);
898void pm_shred(struct part_entry *, int); 898void pm_shred(struct part_entry *, int);
899void pm_umount(struct pm_devs *, int); 899void pm_umount(struct pm_devs *, int);
900int pm_unconfigure(struct pm_devs *); 900int pm_unconfigure(struct pm_devs *);
901int pm_cgd_edit_new(struct pm_devs *pm, part_id id); 901int pm_cgd_edit_new(struct pm_devs *pm, part_id id);
902int pm_cgd_edit_old(struct part_entry *); 902int pm_cgd_edit_old(struct part_entry *);
903void pm_wedges_fill(struct pm_devs *); 903void pm_wedges_fill(struct pm_devs *);
904void pm_edit_partitions(struct part_entry *); 904void pm_edit_partitions(struct part_entry *);
905part_id pm_whole_disk(struct part_entry *, int); 905part_id pm_whole_disk(struct part_entry *, int);
906struct pm_devs * pm_from_pe(struct part_entry *); 906struct pm_devs * pm_from_pe(struct part_entry *);
907bool pm_force_parts(struct pm_devs *); 907bool pm_force_parts(struct pm_devs *);
908 908
909/* 909/*
910 * Parse a file system position or size in a common way, return 910 * Parse a file system position or size in a common way, return
911 * sector count and multiplicator. 911 * sector count and multiplicator.
912 * If "extend" is supported, things like 120+ will be parsed as 912 * If "extend" is supported, things like 120+ will be parsed as
913 * 120 plus "extend this" flag. 913 * 120 plus "extend this" flag.
914 * Caller needs to init muliplicator upfront to the default value. 914 * Caller needs to init muliplicator upfront to the default value.
915 */ 915 */
916daddr_t parse_disk_pos( 916daddr_t parse_disk_pos(
917 const char *, /* in: input string */ 917 const char *, /* in: input string */
918 daddr_t *, /* in/out: multiplicator for return value */ 918 daddr_t *, /* in/out: multiplicator for return value */
919 daddr_t bps, /* in: sector size in bytes */ 919 daddr_t bps, /* in: sector size in bytes */
920 daddr_t, /* in: cylinder size in sectors */ 920 daddr_t, /* in: cylinder size in sectors */
921 bool *); /* NULL if "extend" is not supported, & of 921 bool *); /* NULL if "extend" is not supported, & of
922 * "extend" flag otherwise */ 922 * "extend" flag otherwise */
923 923
924/* flags whether to offer the respective options (depending on helper 924/* flags whether to offer the respective options (depending on helper
925 programs available on install media */ 925 programs available on install media */
926extern int have_raid, have_vnd, have_cgd, have_lvm, have_gpt, have_dk; 926extern int have_raid, have_vnd, have_cgd, have_lvm, have_gpt, have_dk;
927/* initialize above variables */ 927/* initialize above variables */
928void check_available_binaries(void); 928void check_available_binaries(void);
929 929
930/* from bsddisklabel.c */ 930/* from bsddisklabel.c */
931bool make_bsd_partitions(struct install_partition_desc*); 931bool make_bsd_partitions(struct install_partition_desc*);
932void set_ptn_titles(menudesc *, int, void *); 932void set_ptn_titles(menudesc *, int, void *);
933int set_ptn_size(menudesc *, void *); 933int set_ptn_size(menudesc *, void *);
934bool get_ptn_sizes(struct partition_usage_set*); 934bool get_ptn_sizes(struct partition_usage_set*);
935bool check_partitions(struct install_partition_desc*); 935bool check_partitions(struct install_partition_desc*);
936 936
937/* from aout2elf.c */ 937/* from aout2elf.c */
938int move_aout_libs(void); 938int move_aout_libs(void);
939 939
940#ifdef WSKBD 940#ifdef WSKBD
941void get_kb_encoding(void); 941void get_kb_encoding(void);
942void save_kb_encoding(void); 942void save_kb_encoding(void);
943#else 943#else
944#define get_kb_encoding() 944#define get_kb_encoding()
945#define save_kb_encoding() 945#define save_kb_encoding()
946#endif 946#endif
947 947
948/* from configmenu.c */ 948/* from configmenu.c */
949void do_configmenu(struct install_partition_desc*); 949void do_configmenu(struct install_partition_desc*);
950 950
951/* from checkrc.c */ 951/* from checkrc.c */
952int check_rcvar(const char *); 952int check_rcvar(const char *);
953int check_rcdefault(const char *); 953int check_rcdefault(const char *);
954 WINDOW *mainwin; 954extern WINDOW *mainwin;
955 955
956/* in menus.mi */ 956/* in menus.mi */
957void expand_all_option_texts(menudesc *menu, void *arg); 957void expand_all_option_texts(menudesc *menu, void *arg);
958void resize_menu_height(menudesc *); 958void resize_menu_height(menudesc *);
959 959
960#endif /* _DEFS_H_ */ 960#endif /* _DEFS_H_ */

cvs diff -r1.23 -r1.24 src/usr.sbin/sysinst/main.c (switch to unified diff)

--- src/usr.sbin/sysinst/main.c 2020/03/04 11:15:06 1.23
+++ src/usr.sbin/sysinst/main.c 2020/04/22 23:43:12 1.24
@@ -1,570 +1,609 @@ @@ -1,570 +1,609 @@
1/* $NetBSD: main.c,v 1.23 2020/03/04 11:15:06 martin Exp $ */ 1/* $NetBSD: main.c,v 1.24 2020/04/22 23:43:12 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright 1997 Piermont Information Systems Inc. 4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Philip A. Nelson for Piermont Information Systems Inc. 7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse 17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
18 * or promote products derived from this software without specific prior 18 * or promote products derived from this software without specific prior
19 * written permission. 19 * written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE. 31 * THE POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35/* main sysinst program. */ 35/* main sysinst program. */
36 36
37#include <sys/types.h> 37#include <sys/types.h>
38#include <sys/stat.h> 38#include <sys/stat.h>
39#include <sys/syslimits.h> 39#include <sys/syslimits.h>
40#include <sys/uio.h> 40#include <sys/uio.h>
41#include <stdio.h> 41#include <stdio.h>
42#include <signal.h> 42#include <signal.h>
43#include <curses.h> 43#include <curses.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <fcntl.h> 45#include <fcntl.h>
46#include <dirent.h> 46#include <dirent.h>
47#include <locale.h> 47#include <locale.h>
48 48
49#include "defs.h" 49#include "defs.h"
50#include "md.h" 50#include "md.h"
51#include "msg_defs.h" 51#include "msg_defs.h"
52#include "menu_defs.h" 52#include "menu_defs.h"
53#include "txtwalk.h" 53#include "txtwalk.h"
54 54
 55int debug;
 56char machine[SSTRSIZE];
 57int ignorerror;
 58int ttysig_ignore;
 59pid_t ttysig_forward;
 60uint sizemult;
 61int partman_go;
 62FILE *logfp;
 63FILE *script;
 64daddr_t root_limit;
 65struct pm_head_t pm_head;
 66struct pm_devs *pm;
 67struct pm_devs *pm_new;
 68char xfer_dir[STRSIZE];
 69int clean_xfer_dir;
 70char ext_dir_bin[STRSIZE];
 71char ext_dir_src[STRSIZE];
 72char ext_dir_pkgsrc[STRSIZE];
 73char set_dir_bin[STRSIZE];
 74char set_dir_src[STRSIZE];
 75char pkg_dir[STRSIZE];
 76char pkgsrc_dir[STRSIZE];
 77const char *ushell;
 78struct ftpinfo ftp, pkg, pkgsrc;
 79int (*fetch_fn)(const char *);
 80char nfs_host[STRSIZE];
 81char nfs_dir[STRSIZE];
 82char cdrom_dev[SSTRSIZE];
 83char fd_dev[SSTRSIZE];
 84const char *fd_type;
 85char localfs_dev[SSTRSIZE];
 86char localfs_fs[SSTRSIZE];
 87char localfs_dir[STRSIZE];
 88char targetroot_mnt[SSTRSIZE];
 89int mnt2_mounted;
 90char dist_postfix[SSTRSIZE];
 91char dist_tgz_postfix[SSTRSIZE];
 92WINDOW *mainwin;
 93
55static void select_language(void); 94static void select_language(void);
56__dead static void usage(void); 95__dead static void usage(void);
57__dead static void miscsighandler(int); 96__dead static void miscsighandler(int);
58static void ttysighandler(int); 97static void ttysighandler(int);
59static void cleanup(void); 98static void cleanup(void);
60static void process_f_flag(char *); 99static void process_f_flag(char *);
61 100
62static int exit_cleanly = 0; /* Did we finish nicely? */ 101static int exit_cleanly = 0; /* Did we finish nicely? */
63FILE *logfp; /* log file */ 102FILE *logfp; /* log file */
64FILE *script; /* script file */ 103FILE *script; /* script file */
65 104
66const char *multname; 105const char *multname;
67const char *err_outofmem; 106const char *err_outofmem;
68 107
69#ifdef DEBUG 108#ifdef DEBUG
70extern int log_flip(void); 109extern int log_flip(void);
71#endif 110#endif
72 111
73/* Definion for colors */ 112/* Definion for colors */
74 113
75struct { 114struct {
76 unsigned int bg; 115 unsigned int bg;
77 unsigned int fg; 116 unsigned int fg;
78} clr_arg; 117} clr_arg;
79 118
80/* String defaults and stuff for processing the -f file argument. */ 119/* String defaults and stuff for processing the -f file argument. */
81 120
82struct f_arg { 121struct f_arg {
83 const char *name; 122 const char *name;
84 const char *dflt; 123 const char *dflt;
85 char *var; 124 char *var;
86 int size; 125 int size;
87}; 126};
88 127
89static const struct f_arg fflagopts[] = { 128static const struct f_arg fflagopts[] = {
90 {"release", REL, NULL, 0}, 129 {"release", REL, NULL, 0},
91 {"machine", MACH, machine, sizeof machine}, 130 {"machine", MACH, machine, sizeof machine},
92 {"xfer dir", "/usr/INSTALL", xfer_dir, sizeof xfer_dir}, 131 {"xfer dir", "/usr/INSTALL", xfer_dir, sizeof xfer_dir},
93 {"ext dir", "", ext_dir_bin, sizeof ext_dir_bin}, 132 {"ext dir", "", ext_dir_bin, sizeof ext_dir_bin},
94 {"ext src dir", "", ext_dir_src, sizeof ext_dir_src}, 133 {"ext src dir", "", ext_dir_src, sizeof ext_dir_src},
95 {"ftp host", SYSINST_FTP_HOST, ftp.xfer_host[XFER_FTP], sizeof ftp.xfer_host[XFER_FTP]}, 134 {"ftp host", SYSINST_FTP_HOST, ftp.xfer_host[XFER_FTP], sizeof ftp.xfer_host[XFER_FTP]},
96 {"http host", SYSINST_HTTP_HOST, ftp.xfer_host[XFER_HTTP], sizeof ftp.xfer_host[XFER_HTTP]}, 135 {"http host", SYSINST_HTTP_HOST, ftp.xfer_host[XFER_HTTP], sizeof ftp.xfer_host[XFER_HTTP]},
97 {"ftp dir", SYSINST_FTP_DIR, ftp.dir, sizeof ftp.dir}, 136 {"ftp dir", SYSINST_FTP_DIR, ftp.dir, sizeof ftp.dir},
98 {"ftp prefix", "/" ARCH_SUBDIR "/binary/sets", set_dir_bin, sizeof set_dir_bin}, 137 {"ftp prefix", "/" ARCH_SUBDIR "/binary/sets", set_dir_bin, sizeof set_dir_bin},
99 {"ftp src prefix", "/source/sets", set_dir_src, sizeof set_dir_src}, 138 {"ftp src prefix", "/source/sets", set_dir_src, sizeof set_dir_src},
100 {"ftp user", "ftp", ftp.user, sizeof ftp.user}, 139 {"ftp user", "ftp", ftp.user, sizeof ftp.user},
101 {"ftp pass", "", ftp.pass, sizeof ftp.pass}, 140 {"ftp pass", "", ftp.pass, sizeof ftp.pass},
102 {"ftp proxy", "", ftp.proxy, sizeof ftp.proxy}, 141 {"ftp proxy", "", ftp.proxy, sizeof ftp.proxy},
103 {"nfs host", "", nfs_host, sizeof nfs_host}, 142 {"nfs host", "", nfs_host, sizeof nfs_host},
104 {"nfs dir", "/bsd/release", nfs_dir, sizeof nfs_dir}, 143 {"nfs dir", "/bsd/release", nfs_dir, sizeof nfs_dir},
105 {"cd dev", 0, cdrom_dev, sizeof cdrom_dev}, /* default filled in init */ 144 {"cd dev", 0, cdrom_dev, sizeof cdrom_dev}, /* default filled in init */
106 {"fd dev", "/dev/fd0a", fd_dev, sizeof fd_dev}, 145 {"fd dev", "/dev/fd0a", fd_dev, sizeof fd_dev},
107 {"local dev", "", localfs_dev, sizeof localfs_dev}, 146 {"local dev", "", localfs_dev, sizeof localfs_dev},
108 {"local fs", "ffs", localfs_fs, sizeof localfs_fs}, 147 {"local fs", "ffs", localfs_fs, sizeof localfs_fs},
109 {"local dir", "release", localfs_dir, sizeof localfs_dir}, 148 {"local dir", "release", localfs_dir, sizeof localfs_dir},
110 {"targetroot mount", "/targetroot", targetroot_mnt, sizeof targetroot_mnt}, 149 {"targetroot mount", "/targetroot", targetroot_mnt, sizeof targetroot_mnt},
111 {"dist postfix", "." SETS_TAR_SUFF, dist_postfix, sizeof dist_postfix}, 150 {"dist postfix", "." SETS_TAR_SUFF, dist_postfix, sizeof dist_postfix},
112 {"dist tgz postfix", ".tgz", dist_tgz_postfix, sizeof dist_tgz_postfix}, 151 {"dist tgz postfix", ".tgz", dist_tgz_postfix, sizeof dist_tgz_postfix},
113 {"pkg host", SYSINST_PKG_HOST, pkg.xfer_host[XFER_FTP], sizeof pkg.xfer_host[XFER_FTP]}, 152 {"pkg host", SYSINST_PKG_HOST, pkg.xfer_host[XFER_FTP], sizeof pkg.xfer_host[XFER_FTP]},
114 {"pkg http host", SYSINST_PKG_HTTP_HOST, pkg.xfer_host[XFER_HTTP], sizeof pkg.xfer_host[XFER_HTTP]}, 153 {"pkg http host", SYSINST_PKG_HTTP_HOST, pkg.xfer_host[XFER_HTTP], sizeof pkg.xfer_host[XFER_HTTP]},
115 {"pkg dir", SYSINST_PKG_DIR, pkg.dir, sizeof pkg.dir}, 154 {"pkg dir", SYSINST_PKG_DIR, pkg.dir, sizeof pkg.dir},
116 {"pkg prefix", "/" PKG_ARCH_SUBDIR "/" PKG_SUBDIR "/All", pkg_dir, sizeof pkg_dir}, 155 {"pkg prefix", "/" PKG_ARCH_SUBDIR "/" PKG_SUBDIR "/All", pkg_dir, sizeof pkg_dir},
117 {"pkg user", "ftp", pkg.user, sizeof pkg.user}, 156 {"pkg user", "ftp", pkg.user, sizeof pkg.user},
118 {"pkg pass", "", pkg.pass, sizeof pkg.pass}, 157 {"pkg pass", "", pkg.pass, sizeof pkg.pass},
119 {"pkg proxy", "", pkg.proxy, sizeof pkg.proxy}, 158 {"pkg proxy", "", pkg.proxy, sizeof pkg.proxy},
120 {"pkgsrc host", SYSINST_PKGSRC_HOST, pkgsrc.xfer_host[XFER_FTP], sizeof pkgsrc.xfer_host[XFER_FTP]}, 159 {"pkgsrc host", SYSINST_PKGSRC_HOST, pkgsrc.xfer_host[XFER_FTP], sizeof pkgsrc.xfer_host[XFER_FTP]},
121 {"pkgsrc http host", SYSINST_PKGSRC_HTTP_HOST, pkgsrc.xfer_host[XFER_HTTP], sizeof pkgsrc.xfer_host[XFER_HTTP]}, 160 {"pkgsrc http host", SYSINST_PKGSRC_HTTP_HOST, pkgsrc.xfer_host[XFER_HTTP], sizeof pkgsrc.xfer_host[XFER_HTTP]},
122 {"pkgsrc dir", "", pkgsrc.dir, sizeof pkgsrc.dir}, 161 {"pkgsrc dir", "", pkgsrc.dir, sizeof pkgsrc.dir},
123 {"pkgsrc prefix", "pub/pkgsrc/stable", pkgsrc_dir, sizeof pkgsrc_dir}, 162 {"pkgsrc prefix", "pub/pkgsrc/stable", pkgsrc_dir, sizeof pkgsrc_dir},
124 {"pkgsrc user", "ftp", pkgsrc.user, sizeof pkgsrc.user}, 163 {"pkgsrc user", "ftp", pkgsrc.user, sizeof pkgsrc.user},
125 {"pkgsrc pass", "", pkgsrc.pass, sizeof pkgsrc.pass}, 164 {"pkgsrc pass", "", pkgsrc.pass, sizeof pkgsrc.pass},
126 {"pkgsrc proxy", "", pkgsrc.proxy, sizeof pkgsrc.proxy}, 165 {"pkgsrc proxy", "", pkgsrc.proxy, sizeof pkgsrc.proxy},
127 166
128 {NULL, NULL, NULL, 0} 167 {NULL, NULL, NULL, 0}
129}; 168};
130 169
131static void 170static void
132init(void) 171init(void)
133{ 172{
134 const struct f_arg *arg; 173 const struct f_arg *arg;
135  174
136 sizemult = 1; 175 sizemult = 1;
137 clean_xfer_dir = 0; 176 clean_xfer_dir = 0;
138 mnt2_mounted = 0; 177 mnt2_mounted = 0;
139 fd_type = "msdos"; 178 fd_type = "msdos";
140 179
141 pm_head = (struct pm_head_t) SLIST_HEAD_INITIALIZER(pm_head); 180 pm_head = (struct pm_head_t) SLIST_HEAD_INITIALIZER(pm_head);
142 SLIST_INIT(&pm_head); 181 SLIST_INIT(&pm_head);
143 pm_new = malloc(sizeof (struct pm_devs)); 182 pm_new = malloc(sizeof (struct pm_devs));
144 memset(pm_new, 0, sizeof *pm_new); 183 memset(pm_new, 0, sizeof *pm_new);
145 184
146 for (arg = fflagopts; arg->name != NULL; arg++) { 185 for (arg = fflagopts; arg->name != NULL; arg++) {
147 if (arg->var == NULL) 186 if (arg->var == NULL)
148 continue; 187 continue;
149 if (arg->var == cdrom_dev) 188 if (arg->var == cdrom_dev)
150 get_default_cdrom(arg->var, arg->size); 189 get_default_cdrom(arg->var, arg->size);
151 else 190 else
152 strlcpy(arg->var, arg->dflt, arg->size); 191 strlcpy(arg->var, arg->dflt, arg->size);
153 } 192 }
154 pkg.xfer = pkgsrc.xfer = XFER_HTTP; 193 pkg.xfer = pkgsrc.xfer = XFER_HTTP;
155  194
156 clr_arg.bg=COLOR_BLUE; 195 clr_arg.bg=COLOR_BLUE;
157 clr_arg.fg=COLOR_WHITE; 196 clr_arg.fg=COLOR_WHITE;
158} 197}
159 198
160static void 199static void
161init_lang(void) 200init_lang(void)
162{  201{
163 sizemult = 1; 202 sizemult = 1;
164 err_outofmem = msg_string(MSG_out_of_memory); 203 err_outofmem = msg_string(MSG_out_of_memory);
165 multname = msg_string(MSG_secname); 204 multname = msg_string(MSG_secname);
166} 205}
167 206
168int 207int
169main(int argc, char **argv) 208main(int argc, char **argv)
170{ 209{
171 int ch; 210 int ch;
172 211
173 init(); 212 init();
174 213
175#ifdef DEBUG 214#ifdef DEBUG
176 log_flip(); 215 log_flip();
177#endif 216#endif
178 217
179 /* Check for TERM ... */ 218 /* Check for TERM ... */
180 if (!getenv("TERM")) { 219 if (!getenv("TERM")) {
181 (void)fprintf(stderr, 220 (void)fprintf(stderr,
182 "sysinst: environment variable TERM not set.\n"); 221 "sysinst: environment variable TERM not set.\n");
183 exit(4); 222 exit(4);
184 } 223 }
185 224
186 /* argv processing */ 225 /* argv processing */
187 while ((ch = getopt(argc, argv, "Dr:f:C:" 226 while ((ch = getopt(argc, argv, "Dr:f:C:"
188#ifndef NO_PARTMAN 227#ifndef NO_PARTMAN
189 "p" 228 "p"
190#endif 229#endif
191 )) != -1) 230 )) != -1)
192 switch(ch) { 231 switch(ch) {
193 case 'D': /* set to get past certain errors in testing */ 232 case 'D': /* set to get past certain errors in testing */
194 debug = 1; 233 debug = 1;
195 break; 234 break;
196 case 'r': 235 case 'r':
197 /* Release name - ignore for compatibility with older versions */ 236 /* Release name - ignore for compatibility with older versions */
198 break; 237 break;
199 case 'f': 238 case 'f':
200 /* Definition file to read. */ 239 /* Definition file to read. */
201 process_f_flag(optarg); 240 process_f_flag(optarg);
202 break; 241 break;
203 case 'C': 242 case 'C':
204 /* Define colors */ 243 /* Define colors */
205 sscanf(optarg, "%u:%u", &clr_arg.bg, &clr_arg.fg); 244 sscanf(optarg, "%u:%u", &clr_arg.bg, &clr_arg.fg);
206 break; 245 break;
207#ifndef NO_PARTMAN 246#ifndef NO_PARTMAN
208 case 'p': 247 case 'p':
209 /* Partition tool */ 248 /* Partition tool */
210 partman_go = 1; 249 partman_go = 1;
211 break; 250 break;
212#endif 251#endif
213 case '?': 252 case '?':
214 default: 253 default:
215 usage(); 254 usage();
216 } 255 }
217 256
218 md_init(); 257 md_init();
219 258
220 /* Initialize the partitioning subsystem */ 259 /* Initialize the partitioning subsystem */
221 partitions_init(); 260 partitions_init();
222 261
223 /* initialize message window */ 262 /* initialize message window */
224 if (menu_init()) { 263 if (menu_init()) {
225 __menu_initerror(); 264 __menu_initerror();
226 exit(4); 265 exit(4);
227 } 266 }
228 267
229 /* 268 /*
230 * Put 'messages' in a window that has a one-character border 269 * Put 'messages' in a window that has a one-character border
231 * on the real screen. 270 * on the real screen.
232 */ 271 */
233 mainwin = newwin(getmaxy(stdscr) - 2, getmaxx(stdscr) - 2, 1, 1); 272 mainwin = newwin(getmaxy(stdscr) - 2, getmaxx(stdscr) - 2, 1, 1);
234 if (mainwin == NULL) { 273 if (mainwin == NULL) {
235 (void)fprintf(stderr, 274 (void)fprintf(stderr,
236 "sysinst: screen too small\n"); 275 "sysinst: screen too small\n");
237 exit(1); 276 exit(1);
238 } 277 }
239 if (has_colors()) { 278 if (has_colors()) {
240 start_color(); 279 start_color();
241 do_coloring(clr_arg.fg,clr_arg.bg); 280 do_coloring(clr_arg.fg,clr_arg.bg);
242 } else { 281 } else {
243 remove_color_options(); 282 remove_color_options();
244 } 283 }
245 msg_window(mainwin); 284 msg_window(mainwin);
246 285
247 /* Watch for signals and clean up */ 286 /* Watch for signals and clean up */
248 (void)atexit(cleanup); 287 (void)atexit(cleanup);
249 (void)signal(SIGINT, ttysighandler); 288 (void)signal(SIGINT, ttysighandler);
250 (void)signal(SIGQUIT, ttysighandler); 289 (void)signal(SIGQUIT, ttysighandler);
251 (void)signal(SIGHUP, miscsighandler); 290 (void)signal(SIGHUP, miscsighandler);
252 291
253 /* redraw screen */ 292 /* redraw screen */
254 touchwin(stdscr); 293 touchwin(stdscr);
255 refresh(); 294 refresh();
256 295
257 /* Ensure we have mountpoint for target filesystems */ 296 /* Ensure we have mountpoint for target filesystems */
258 mkdir(targetroot_mnt, S_IRWXU| S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH); 297 mkdir(targetroot_mnt, S_IRWXU| S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
259 298
260 select_language(); 299 select_language();
261 get_kb_encoding(); 300 get_kb_encoding();
262 init_lang(); 301 init_lang();
263 302
264 /* Menu processing */ 303 /* Menu processing */
265 if (partman_go) 304 if (partman_go)
266 partman(); 305 partman();
267 else 306 else
268 process_menu(MENU_netbsd, NULL); 307 process_menu(MENU_netbsd, NULL);
269 308
270#ifndef NO_PARTMAN 309#ifndef NO_PARTMAN
271 /* clean up internal storage */ 310 /* clean up internal storage */
272 pm_destroy_all(); 311 pm_destroy_all();
273#endif 312#endif
274 313
275 partitions_cleanup(); 314 partitions_cleanup();
276 315
277 exit_cleanly = 1; 316 exit_cleanly = 1;
278 return 0; 317 return 0;
279} 318}
280 319
281static int 320static int
282set_language(menudesc *m, void *arg) 321set_language(menudesc *m, void *arg)
283{ 322{
284 char **fnames = arg; 323 char **fnames = arg;
285 324
286 msg_file(fnames[m->cursel]); 325 msg_file(fnames[m->cursel]);
287 return 1; 326 return 1;
288} 327}
289 328
290static void 329static void
291select_language(void) 330select_language(void)
292{ 331{
293 DIR *dir; 332 DIR *dir;
294 struct dirent *dirent; 333 struct dirent *dirent;
295 char **lang_msg, **fnames; 334 char **lang_msg, **fnames;
296 char prefix[PATH_MAX], fname[PATH_MAX]; 335 char prefix[PATH_MAX], fname[PATH_MAX];
297 int max_lang = 16, num_lang = 0; 336 int max_lang = 16, num_lang = 0;
298 const char *cp; 337 const char *cp;
299 menu_ent *opt = 0; 338 menu_ent *opt = 0;
300 int lang_menu = -1; 339 int lang_menu = -1;
301 int lang; 340 int lang;
302 341
303#ifdef CATALOG_DIR 342#ifdef CATALOG_DIR
304 strcpy(prefix, CATALOG_DIR "/"); 343 strcpy(prefix, CATALOG_DIR "/");
305 dir = opendir(CATALOG_DIR); 344 dir = opendir(CATALOG_DIR);
306 if (!dir) { 345 if (!dir) {
307 strcpy(prefix, "./"); 346 strcpy(prefix, "./");
308 dir = opendir("."); 347 dir = opendir(".");
309 } 348 }
310#else 349#else
311 dir = opendir("."); 350 dir = opendir(".");
312 strcpy(prefix, "./"); 351 strcpy(prefix, "./");
313#endif 352#endif
314 if (!dir) 353 if (!dir)
315 return; 354 return;
316 355
317 lang_msg = malloc(max_lang * sizeof *lang_msg); 356 lang_msg = malloc(max_lang * sizeof *lang_msg);
318 fnames = malloc(max_lang * sizeof *fnames); 357 fnames = malloc(max_lang * sizeof *fnames);
319 if (!lang_msg || !fnames) 358 if (!lang_msg || !fnames)
320 goto done; 359 goto done;
321 360
322 lang_msg[0] = strdup(msg_string(MSG_sysinst_message_language)); 361 lang_msg[0] = strdup(msg_string(MSG_sysinst_message_language));
323 fnames[0] = 0; 362 fnames[0] = 0;
324 num_lang = 1; 363 num_lang = 1;
325 364
326 while ((dirent = readdir(dir)) != 0) { 365 while ((dirent = readdir(dir)) != 0) {
327 if (memcmp(dirent->d_name, "sysinstmsgs.", 12)) 366 if (memcmp(dirent->d_name, "sysinstmsgs.", 12))
328 continue; 367 continue;
329 strcpy(fname, prefix); 368 strcpy(fname, prefix);
330 strcat(fname, dirent->d_name); 369 strcat(fname, dirent->d_name);
331 if (msg_file(fname)) 370 if (msg_file(fname))
332 continue; 371 continue;
333 cp = msg_string(MSG_sysinst_message_language); 372 cp = msg_string(MSG_sysinst_message_language);
334 if (!strcmp(cp, lang_msg[0])) 373 if (!strcmp(cp, lang_msg[0]))
335 continue; 374 continue;
336 if (num_lang == max_lang) { 375 if (num_lang == max_lang) {
337 char **new; 376 char **new;
338 max_lang *= 2; 377 max_lang *= 2;
339 new = realloc(lang_msg, max_lang * sizeof *lang_msg); 378 new = realloc(lang_msg, max_lang * sizeof *lang_msg);
340 if (!new) 379 if (!new)
341 break; 380 break;
342 lang_msg = new; 381 lang_msg = new;
343 new = realloc(fnames, max_lang * sizeof *fnames); 382 new = realloc(fnames, max_lang * sizeof *fnames);
344 if (!new) 383 if (!new)
345 break; 384 break;
346 fnames = new; 385 fnames = new;
347 } 386 }
348 fnames[num_lang] = strdup(fname); 387 fnames[num_lang] = strdup(fname);
349 lang_msg[num_lang++] = strdup(cp); 388 lang_msg[num_lang++] = strdup(cp);
350 } 389 }
351 msg_file(0); 390 msg_file(0);
352 closedir(dir); 391 closedir(dir);
353 dir = 0; 392 dir = 0;
354 393
355 if (num_lang == 1) 394 if (num_lang == 1)
356 goto done; 395 goto done;
357 396
358 opt = calloc(num_lang, sizeof *opt); 397 opt = calloc(num_lang, sizeof *opt);
359 if (!opt) 398 if (!opt)
360 goto done; 399 goto done;
361 400
362 for (lang = 0; lang < num_lang; lang++) { 401 for (lang = 0; lang < num_lang; lang++) {
363 opt[lang].opt_name = lang_msg[lang]; 402 opt[lang].opt_name = lang_msg[lang];
364 opt[lang].opt_action = set_language; 403 opt[lang].opt_action = set_language;
365 } 404 }
366 405
367 lang_menu = new_menu(NULL, opt, num_lang, -1, 12, 0, 0, MC_NOEXITOPT, 406 lang_menu = new_menu(NULL, opt, num_lang, -1, 12, 0, 0, MC_NOEXITOPT,
368 NULL, NULL, NULL, NULL, NULL); 407 NULL, NULL, NULL, NULL, NULL);
369 408
370 if (lang_menu != -1) { 409 if (lang_menu != -1) {
371 msg_display(MSG_hello); 410 msg_display(MSG_hello);
372 process_menu(lang_menu, fnames); 411 process_menu(lang_menu, fnames);
373 } 412 }
374 413
375 done: 414 done:
376 if (dir) 415 if (dir)
377 closedir(dir); 416 closedir(dir);
378 if (lang_menu != -1) 417 if (lang_menu != -1)
379 free_menu(lang_menu); 418 free_menu(lang_menu);
380 free(opt); 419 free(opt);
381 while (num_lang) { 420 while (num_lang) {
382 free(lang_msg[--num_lang]); 421 free(lang_msg[--num_lang]);
383 free(fnames[num_lang]); 422 free(fnames[num_lang]);
384 } 423 }
385 free(lang_msg); 424 free(lang_msg);
386 free(fnames); 425 free(fnames);
387 426
388 /* set locale according to selected language */ 427 /* set locale according to selected language */
389 cp = msg_string(MSG_sysinst_message_locale); 428 cp = msg_string(MSG_sysinst_message_locale);
390 if (cp) { 429 if (cp) {
391 setlocale(LC_CTYPE, cp); 430 setlocale(LC_CTYPE, cp);
392 setenv("LC_CTYPE", cp, 1); 431 setenv("LC_CTYPE", cp, 1);
393 } 432 }
394} 433}
395 434
396#ifndef md_may_remove_boot_medium 435#ifndef md_may_remove_boot_medium
397#define md_may_remove_boot_medium() (boot_media_still_needed()<=0) 436#define md_may_remove_boot_medium() (boot_media_still_needed()<=0)
398#endif 437#endif
399 438
400/* toplevel menu handler ... */ 439/* toplevel menu handler ... */
401void 440void
402toplevel(void) 441toplevel(void)
403{ 442{
404 /* 443 /*
405 * Undo any stateful side-effects of previous menu choices. 444 * Undo any stateful side-effects of previous menu choices.
406 * XXX must be idempotent, since we get run each time the main 445 * XXX must be idempotent, since we get run each time the main
407 * menu is displayed. 446 * menu is displayed.
408 */ 447 */
409 char *home = getenv("HOME"); 448 char *home = getenv("HOME");
410 if (home != NULL) 449 if (home != NULL)
411 if (chdir(home) != 0) 450 if (chdir(home) != 0)
412 (void)chdir("/"); 451 (void)chdir("/");
413 unwind_mounts(); 452 unwind_mounts();
414 453
415 /* Display banner message in (english, francais, deutsch..) */ 454 /* Display banner message in (english, francais, deutsch..) */
416 msg_display(MSG_hello); 455 msg_display(MSG_hello);
417 msg_display_add(MSG_md_hello); 456 msg_display_add(MSG_md_hello);
418 if (md_may_remove_boot_medium()) 457 if (md_may_remove_boot_medium())
419 msg_display_add(MSG_md_may_remove_boot_medium); 458 msg_display_add(MSG_md_may_remove_boot_medium);
420 msg_display_add(MSG_thanks); 459 msg_display_add(MSG_thanks);
421} 460}
422 461
423 462
424/* The usage ... */ 463/* The usage ... */
425 464
426static void 465static void
427usage(void) 466usage(void)
428{ 467{
429 468
430 (void)fprintf(stderr, "usage: sysinst [-D] [-f definition_file] " 469 (void)fprintf(stderr, "usage: sysinst [-D] [-f definition_file] "
431 "[-r release] [-C bg:fg]" 470 "[-r release] [-C bg:fg]"
432#ifndef NO_PARTMAN 471#ifndef NO_PARTMAN
433 " [-p]" 472 " [-p]"
434#endif 473#endif
435 "\n" 474 "\n"
436 "where:\n" 475 "where:\n"
437 "\t-D\n\t\trun in debug mode\n" 476 "\t-D\n\t\trun in debug mode\n"
438 "\t-f definition_file\n\t\toverride built-in defaults from file\n" 477 "\t-f definition_file\n\t\toverride built-in defaults from file\n"
439 "\t-r release\n\t\toverride release name\n" 478 "\t-r release\n\t\toverride release name\n"
440 "\t-C bg:fg\n\t\tuse different color scheme\n" 479 "\t-C bg:fg\n\t\tuse different color scheme\n"
441#ifndef NO_PARTMAN 480#ifndef NO_PARTMAN
442 "\t-p\n\t\tonly run the partition editor, no installation\n" 481 "\t-p\n\t\tonly run the partition editor, no installation\n"
443#endif 482#endif
444 ); 483 );
445 484
446 exit(1); 485 exit(1);
447} 486}
448 487
449/* ARGSUSED */ 488/* ARGSUSED */
450static void 489static void
451miscsighandler(int signo) 490miscsighandler(int signo)
452{ 491{
453 492
454 /* 493 /*
455 * we need to cleanup(), but it was already scheduled with atexit(), 494 * we need to cleanup(), but it was already scheduled with atexit(),
456 * so it'll be invoked on exit(). 495 * so it'll be invoked on exit().
457 */ 496 */
458 exit(1); 497 exit(1);
459} 498}
460 499
461static void 500static void
462ttysighandler(int signo) 501ttysighandler(int signo)
463{ 502{
464 503
465 /* 504 /*
466 * if we want to ignore a TTY signal (SIGINT or SIGQUIT), then we 505 * if we want to ignore a TTY signal (SIGINT or SIGQUIT), then we
467 * just return. If we want to forward a TTY signal, we forward it 506 * just return. If we want to forward a TTY signal, we forward it
468 * to the specified process group. 507 * to the specified process group.
469 * 508 *
470 * This functionality is used when setting up and displaying child 509 * This functionality is used when setting up and displaying child
471 * output so that the child gets the signal and presumably dies, 510 * output so that the child gets the signal and presumably dies,
472 * but sysinst continues. We use this rather than actually ignoring 511 * but sysinst continues. We use this rather than actually ignoring
473 * the signals, because that will be be passed on to a child 512 * the signals, because that will be be passed on to a child
474 * through fork/exec, whereas special handlers get reset on exec.. 513 * through fork/exec, whereas special handlers get reset on exec..
475 */ 514 */
476 if (ttysig_ignore) 515 if (ttysig_ignore)
477 return; 516 return;
478 if (ttysig_forward) { 517 if (ttysig_forward) {
479 killpg(ttysig_forward, signo); 518 killpg(ttysig_forward, signo);
480 return; 519 return;
481 } 520 }
482 521
483 /* 522 /*
484 * we need to cleanup(), but it was already scheduled with atexit(), 523 * we need to cleanup(), but it was already scheduled with atexit(),
485 * so it'll be invoked on exit(). 524 * so it'll be invoked on exit().
486 */ 525 */
487 exit(1); 526 exit(1);
488} 527}
489 528
490static void 529static void
491cleanup(void) 530cleanup(void)
492{ 531{
493 time_t tloc; 532 time_t tloc;
494 533
495 (void)time(&tloc); 534 (void)time(&tloc);
496 535
497#if 0 536#if 0
498 restore_etc(); 537 restore_etc();
499#endif 538#endif
500 /* Ensure we aren't inside the target tree */ 539 /* Ensure we aren't inside the target tree */
501 chdir(getenv("HOME")); 540 chdir(getenv("HOME"));
502 unwind_mounts(); 541 unwind_mounts();
503 umount_mnt2(); 542 umount_mnt2();
504 543
505 endwin(); 544 endwin();
506 545
507 if (logfp) { 546 if (logfp) {
508 fprintf(logfp, "Log ended at: %s\n", safectime(&tloc)); 547 fprintf(logfp, "Log ended at: %s\n", safectime(&tloc));
509 fflush(logfp); 548 fflush(logfp);
510 fclose(logfp); 549 fclose(logfp);
511 logfp = NULL; 550 logfp = NULL;
512 } 551 }
513 if (script) { 552 if (script) {
514 fprintf(script, "# Script ended at: %s\n", safectime(&tloc)); 553 fprintf(script, "# Script ended at: %s\n", safectime(&tloc));
515 fflush(script); 554 fflush(script);
516 fclose(script); 555 fclose(script);
517 script = NULL; 556 script = NULL;
518 } 557 }
519 558
520 if (!exit_cleanly) 559 if (!exit_cleanly)
521 fprintf(stderr, "\n\nsysinst terminated.\n"); 560 fprintf(stderr, "\n\nsysinst terminated.\n");
522} 561}
523 562
524 563
525/* process function ... */ 564/* process function ... */
526 565
527void 566void
528process_f_flag(char *f_name) 567process_f_flag(char *f_name)
529{ 568{
530 char buffer[STRSIZE]; 569 char buffer[STRSIZE];
531 int len; 570 int len;
532 const struct f_arg *arg; 571 const struct f_arg *arg;
533 FILE *fp; 572 FILE *fp;
534 char *cp, *cp1, *err; 573 char *cp, *cp1, *err;
535 574
536 /* open the file */ 575 /* open the file */
537 fp = fopen(f_name, "r"); 576 fp = fopen(f_name, "r");
538 if (fp == NULL) { 577 if (fp == NULL) {
539 const char *args[] = { f_name }; 578 const char *args[] = { f_name };
540 err = str_arg_subst(msg_string(MSG_config_open_error), 579 err = str_arg_subst(msg_string(MSG_config_open_error),
541 __arraycount(args), args); 580 __arraycount(args), args);
542 fprintf(stderr, "%s\n", err); 581 fprintf(stderr, "%s\n", err);
543 free(err); 582 free(err);
544 exit(1); 583 exit(1);
545 } 584 }
546 585
547 while (fgets(buffer, sizeof buffer, fp) != NULL) { 586 while (fgets(buffer, sizeof buffer, fp) != NULL) {
548 cp = buffer + strspn(buffer, " \t"); 587 cp = buffer + strspn(buffer, " \t");
549 if (strchr("#\r\n", *cp) != NULL) 588 if (strchr("#\r\n", *cp) != NULL)
550 continue; 589 continue;
551 for (arg = fflagopts; arg->name != NULL; arg++) { 590 for (arg = fflagopts; arg->name != NULL; arg++) {
552 len = strlen(arg->name); 591 len = strlen(arg->name);
553 if (memcmp(cp, arg->name, len) != 0) 592 if (memcmp(cp, arg->name, len) != 0)
554 continue; 593 continue;
555 if (arg->var == NULL || arg->size == 0) 594 if (arg->var == NULL || arg->size == 0)
556 continue; 595 continue;
557 cp1 = cp + len; 596 cp1 = cp + len;
558 cp1 += strspn(cp1, " \t"); 597 cp1 += strspn(cp1, " \t");
559 if (*cp1++ != '=') 598 if (*cp1++ != '=')
560 continue; 599 continue;
561 cp1 += strspn(cp1, " \t"); 600 cp1 += strspn(cp1, " \t");
562 len = strcspn(cp1, " \n\r\t"); 601 len = strcspn(cp1, " \n\r\t");
563 cp1[len] = 0; 602 cp1[len] = 0;
564 strlcpy(arg->var, cp1, arg->size); 603 strlcpy(arg->var, cp1, arg->size);
565 break; 604 break;
566 } 605 }
567 } 606 }
568 607
569 fclose(fp); 608 fclose(fp);
570} 609}

cvs diff -r1.31 -r1.32 src/usr.sbin/sysinst/mbr.c (switch to unified diff)

--- src/usr.sbin/sysinst/mbr.c 2020/02/06 18:07:22 1.31
+++ src/usr.sbin/sysinst/mbr.c 2020/04/22 23:43:12 1.32
@@ -1,1146 +1,1146 @@ @@ -1,1146 +1,1146 @@
1/* $NetBSD: mbr.c,v 1.31 2020/02/06 18:07:22 martin Exp $ */ 1/* $NetBSD: mbr.c,v 1.32 2020/04/22 23:43:12 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright 1997 Piermont Information Systems Inc. 4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Philip A. Nelson for Piermont Information Systems Inc. 7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse 17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
18 * or promote products derived from this software without specific prior 18 * or promote products derived from this software without specific prior
19 * written permission. 19 * written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE. 31 * THE POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35/* 35/*
36 * Following applies to the geometry guessing code 36 * Following applies to the geometry guessing code
37 */ 37 */
38 38
39/* 39/*
40 * Mach Operating System 40 * Mach Operating System
41 * Copyright (c) 1992 Carnegie Mellon University 41 * Copyright (c) 1992 Carnegie Mellon University
42 * All Rights Reserved. 42 * All Rights Reserved.
43 * 43 *
44 * Permission to use, copy, modify and distribute this software and its 44 * Permission to use, copy, modify and distribute this software and its
45 * documentation is hereby granted, provided that both the copyright 45 * documentation is hereby granted, provided that both the copyright
46 * notice and this permission notice appear in all copies of the 46 * notice and this permission notice appear in all copies of the
47 * software, derivative works or modified versions, and any portions 47 * software, derivative works or modified versions, and any portions
48 * thereof, and that both notices appear in supporting documentation. 48 * thereof, and that both notices appear in supporting documentation.
49 * 49 *
50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
52 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 52 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 * 53 *
54 * Carnegie Mellon requests users of this software to return to 54 * Carnegie Mellon requests users of this software to return to
55 * 55 *
56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science 57 * School of Computer Science
58 * Carnegie Mellon University 58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890 59 * Pittsburgh PA 15213-3890
60 * 60 *
61 * any improvements or extensions that they make and grant Carnegie Mellon 61 * any improvements or extensions that they make and grant Carnegie Mellon
62 * the rights to redistribute these changes. 62 * the rights to redistribute these changes.
63 */ 63 */
64 64
65/* mbr.c -- DOS Master Boot Record editing code */ 65/* mbr.c -- DOS Master Boot Record editing code */
66 66
67#ifdef HAVE_MBR 67#ifdef HAVE_MBR
68 68
69#include <sys/param.h> 69#include <sys/param.h>
70#include <sys/types.h> 70#include <sys/types.h>
71#include <assert.h> 71#include <assert.h>
72#include <stdio.h> 72#include <stdio.h>
73#include <stdlib.h> 73#include <stdlib.h>
74#include <unistd.h> 74#include <unistd.h>
75#include <fcntl.h> 75#include <fcntl.h>
76#include <util.h> 76#include <util.h>
77#include <paths.h> 77#include <paths.h>
78#include <sys/ioctl.h> 78#include <sys/ioctl.h>
79#include "defs.h" 79#include "defs.h"
80#include "mbr.h" 80#include "mbr.h"
81#include "md.h" 81#include "md.h"
82#include "msg_defs.h" 82#include "msg_defs.h"
83#include "menu_defs.h" 83#include "menu_defs.h"
84#include "defsizes.h" 84#include "defsizes.h"
85#include "endian.h" 85#include "endian.h"
86 86
87#define NO_BOOTMENU (-0x100) 87#define NO_BOOTMENU (-0x100)
88 88
89#define MAXCYL 1023 /* Possibly 1024 */ 89#define MAXCYL 1023 /* Possibly 1024 */
90#define MAXHEAD 255 /* Possibly 256 */ 90#define MAXHEAD 255 /* Possibly 256 */
91#define MAXSECTOR 63 91#define MAXSECTOR 63
92 92
93 93
94#define MBR_UNKNOWN_PTYPE 94 /* arbitrary not widely used value */ 94#define MBR_UNKNOWN_PTYPE 94 /* arbitrary not widely used value */
95 95
96 96
97/* A list of predefined partition types */ 97/* A list of predefined partition types */
98const struct { 98const struct {
99 unsigned int ptype; 99 unsigned int ptype;
100 char short_desc[12]; 100 char short_desc[12];
101 const char *desc; 101 const char *desc;
102} mbr_part_types_src[] = { 102} mbr_part_types_src[] = {
103 { .ptype=MBR_PTYPE_NETBSD, .desc="NetBSD" }, 103 { .ptype=MBR_PTYPE_NETBSD, .desc="NetBSD" },
104 { .ptype=MBR_PTYPE_FAT32L, .desc="Windows FAT32, LBA" }, 104 { .ptype=MBR_PTYPE_FAT32L, .desc="Windows FAT32, LBA" },
105 { .ptype=MBR_PTYPE_EXT_LBA, .desc="Extended partition, LBA" }, 105 { .ptype=MBR_PTYPE_EXT_LBA, .desc="Extended partition, LBA" },
106 { .ptype=MBR_PTYPE_386BSD, .desc="FreeBSD/386BSD" }, 106 { .ptype=MBR_PTYPE_386BSD, .desc="FreeBSD/386BSD" },
107 { .ptype=MBR_PTYPE_OPENBSD, .desc="OpenBSD" }, 107 { .ptype=MBR_PTYPE_OPENBSD, .desc="OpenBSD" },
108 { .ptype=MBR_PTYPE_LNXEXT2, .desc="Linux native" }, 108 { .ptype=MBR_PTYPE_LNXEXT2, .desc="Linux native" },
109 { .ptype=MBR_PTYPE_LNXSWAP, .desc="Linux swap" }, 109 { .ptype=MBR_PTYPE_LNXSWAP, .desc="Linux swap" },
110 { .ptype=MBR_PTYPE_NTFSVOL, .desc="NTFS volume set" }, 110 { .ptype=MBR_PTYPE_NTFSVOL, .desc="NTFS volume set" },
111 { .ptype=MBR_PTYPE_NTFS, .desc="NTFS" }, 111 { .ptype=MBR_PTYPE_NTFS, .desc="NTFS" },
112 { .ptype=MBR_PTYPE_PREP, .desc="PReP Boot" }, 112 { .ptype=MBR_PTYPE_PREP, .desc="PReP Boot" },
113#ifdef MBR_PTYPE_SOLARIS 113#ifdef MBR_PTYPE_SOLARIS
114 { .ptype=MBR_PTYPE_SOLARIS, .desc="Solaris" }, 114 { .ptype=MBR_PTYPE_SOLARIS, .desc="Solaris" },
115#endif 115#endif
116 { .ptype=MBR_PTYPE_FAT12, .desc="DOS FAT12" }, 116 { .ptype=MBR_PTYPE_FAT12, .desc="DOS FAT12" },
117 { .ptype=MBR_PTYPE_FAT16S, .desc="DOS FAT16, <32M" }, 117 { .ptype=MBR_PTYPE_FAT16S, .desc="DOS FAT16, <32M" },
118 { .ptype=MBR_PTYPE_FAT16B, .desc="DOS FAT16, >32M" }, 118 { .ptype=MBR_PTYPE_FAT16B, .desc="DOS FAT16, >32M" },
119 { .ptype=MBR_PTYPE_FAT16L, .desc="Windows FAT16, LBA" }, 119 { .ptype=MBR_PTYPE_FAT16L, .desc="Windows FAT16, LBA" },
120 { .ptype=MBR_PTYPE_FAT32, .desc="Windows FAT32" }, 120 { .ptype=MBR_PTYPE_FAT32, .desc="Windows FAT32" },
121 { .ptype=MBR_PTYPE_EFI, .desc="(U)EFI Boot" }, 121 { .ptype=MBR_PTYPE_EFI, .desc="(U)EFI Boot" },
122}; 122};
123 123
124/* bookeeping of available partition types (including custom ones) */ 124/* bookeeping of available partition types (including custom ones) */
125struct mbr_part_type_info { 125struct mbr_part_type_info {
126 struct part_type_desc gen; /* generic description */ 126 struct part_type_desc gen; /* generic description */
127 char desc_buf[40], short_buf[10]; 127 char desc_buf[40], short_buf[10];
128 size_t next_ptype; /* user interface order */ 128 size_t next_ptype; /* user interface order */
129}; 129};
130 130
131const struct disk_partitioning_scheme mbr_parts; 131const struct disk_partitioning_scheme mbr_parts;
132struct mbr_disk_partitions { 132struct mbr_disk_partitions {
133 struct disk_partitions dp, *dlabel; 133 struct disk_partitions dp, *dlabel;
134 mbr_info_t mbr; 134 mbr_info_t mbr;
135 uint ptn_alignment, ptn_0_offset, ext_ptn_alignment, 135 uint ptn_alignment, ptn_0_offset, ext_ptn_alignment,
136 geo_sec, geo_head, geo_cyl; 136 geo_sec, geo_head, geo_cyl;
137}; 137};
138 138
139const struct disk_partitioning_scheme mbr_parts; 139const struct disk_partitioning_scheme mbr_parts;
140 140
141static size_t known_part_types = 0, last_added_part_type = 0; 141static size_t known_part_types = 0, last_added_part_type = 0;
142static const size_t first_part_type = MBR_PTYPE_NETBSD; 142static const size_t first_part_type = MBR_PTYPE_NETBSD;
143 143
144/* all partition types (we are lucky, only a fixed number is possible) */ 144/* all partition types (we are lucky, only a fixed number is possible) */
145struct mbr_part_type_info mbr_gen_type_desc[256]; 145struct mbr_part_type_info mbr_gen_type_desc[256];
146 146
147const struct disk_partitioning_scheme disklabel_parts; 147extern const struct disk_partitioning_scheme disklabel_parts;
148 148
149static void convert_mbr_chs(int, int, int, uint8_t *, uint8_t *, 149static void convert_mbr_chs(int, int, int, uint8_t *, uint8_t *,
150 uint8_t *, uint32_t); 150 uint8_t *, uint32_t);
151 151
152static part_id mbr_add_part(struct disk_partitions *arg, 152static part_id mbr_add_part(struct disk_partitions *arg,
153 const struct disk_part_info *info, const char **errmsg); 153 const struct disk_part_info *info, const char **errmsg);
154 154
155static size_t mbr_get_free_spaces(const struct disk_partitions *arg, 155static size_t mbr_get_free_spaces(const struct disk_partitions *arg,
156 struct disk_part_free_space *result, size_t max_num_result, 156 struct disk_part_free_space *result, size_t max_num_result,
157 daddr_t min_size, daddr_t align, daddr_t lower_bound, daddr_t ignore); 157 daddr_t min_size, daddr_t align, daddr_t lower_bound, daddr_t ignore);
158 158
159static size_t mbr_type_from_gen_desc(const struct part_type_desc *desc); 159static size_t mbr_type_from_gen_desc(const struct part_type_desc *desc);
160 160
161/* 161/*
162 * Notes on the extended partition editor. 162 * Notes on the extended partition editor.
163 * 163 *
164 * The extended partition structure is actually a singly linked list. 164 * The extended partition structure is actually a singly linked list.
165 * Each of the 'mbr' sectors can only contain 2 items, the first describes 165 * Each of the 'mbr' sectors can only contain 2 items, the first describes
166 * a user partition (relative to that mbr sector), the second describes 166 * a user partition (relative to that mbr sector), the second describes
167 * the following partition (relative to the start of the extended partition). 167 * the following partition (relative to the start of the extended partition).
168 * 168 *
169 * The 'start' sector for the user partition is always the size of one 169 * The 'start' sector for the user partition is always the size of one
170 * track - very often 63. The extended partitions themselves should 170 * track - very often 63. The extended partitions themselves should
171 * always start on a cylinder boundary using the BIOS geometry - often 171 * always start on a cylinder boundary using the BIOS geometry - often
172 * 16065 sectors per cylinder. 172 * 16065 sectors per cylinder.
173 * 173 *
174 * The disk is also always described in increasing sector order. 174 * The disk is also always described in increasing sector order.
175 * 175 *
176 * During editing we keep the mbr sectors accurate (it might have been 176 * During editing we keep the mbr sectors accurate (it might have been
177 * easier to use absolute sector numbers though), and keep a copy of the 177 * easier to use absolute sector numbers though), and keep a copy of the
178 * entire sector - to preserve any information any other OS has tried 178 * entire sector - to preserve any information any other OS has tried
179 * to squirrel away in the (apparently) unused space. 179 * to squirrel away in the (apparently) unused space.
180 * 180 *
181 * Typical disk (with some small numbers): 181 * Typical disk (with some small numbers):
182 * 182 *
183 * 0 -> a 63 37 dos 183 * 0 -> a 63 37 dos
184 * b 100 1000 extended LBA (type 15) 184 * b 100 1000 extended LBA (type 15)
185 * 185 *
186 * 100 -> a 63 37 user 186 * 100 -> a 63 37 user
187 * b 100 200 extended partiton (type 5) 187 * b 100 200 extended partiton (type 5)
188 * 188 *
189 * 200 -> a 63 37 user 189 * 200 -> a 63 37 user
190 * b 200 300 extended partiton (type 5) 190 * b 200 300 extended partiton (type 5)
191 * 191 *
192 * 300 -> a 63 37 user 192 * 300 -> a 63 37 user
193 * b 0 0 0 (end of chain) 193 * b 0 0 0 (end of chain)
194 * 194 *
195 */ 195 */
196 196
197#ifndef debug_extended 197#ifndef debug_extended
198#define dump_mbr(mbr, msg) 198#define dump_mbr(mbr, msg)
199#else 199#else
200static void 200static void
201dump_mbr(mbr_info_t *m, const char *label) 201dump_mbr(mbr_info_t *m, const char *label)
202{ 202{
203 int i; 203 int i;
204 uint ext_base = 0; 204 uint ext_base = 0;
205 205
206 fprintf(stderr, "\n%s: bsec %d\n", label, bsec); 206 fprintf(stderr, "\n%s: bsec %d\n", label, bsec);
207 do { 207 do {
208 fprintf(stderr, "%p: %12u %p\n", 208 fprintf(stderr, "%p: %12u %p\n",
209 m, m->sector, m->extended); 209 m, m->sector, m->extended);
210 for (i = 0; i < MBR_PART_COUNT; i++) { 210 for (i = 0; i < MBR_PART_COUNT; i++) {
211 fprintf(stderr, " %*d %12u %12u %12" PRIu64, 211 fprintf(stderr, " %*d %12u %12u %12" PRIu64,
212 10, 212 10,
213 m->mbr.mbr_parts[i].mbrp_type, 213 m->mbr.mbr_parts[i].mbrp_type,
214 m->mbr.mbr_parts[i].mbrp_start, 214 m->mbr.mbr_parts[i].mbrp_start,
215 m->mbr.mbr_parts[i].mbrp_size, 215 m->mbr.mbr_parts[i].mbrp_size,
216 (uint64_t)m->mbr.mbr_parts[i].mbrp_start + 216 (uint64_t)m->mbr.mbr_parts[i].mbrp_start +
217 (uint64_t)m->mbr.mbr_parts[i].mbrp_size); 217 (uint64_t)m->mbr.mbr_parts[i].mbrp_size);
218 if (m->sector == 0 && 218 if (m->sector == 0 &&
219 MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type)) 219 MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type))
220 ext_base = m->mbr.mbr_parts[i].mbrp_start; 220 ext_base = m->mbr.mbr_parts[i].mbrp_start;
221 if (m->sector > 0 && 221 if (m->sector > 0 &&
222 m->mbr.mbr_parts[i].mbrp_size > 0) { 222 m->mbr.mbr_parts[i].mbrp_size > 0) {
223 uint off = MBR_IS_EXTENDED( 223 uint off = MBR_IS_EXTENDED(
224 m->mbr.mbr_parts[i].mbrp_type) 224 m->mbr.mbr_parts[i].mbrp_type)
225 ? ext_base : m->sector; 225 ? ext_base : m->sector;
226 fprintf(stderr, " -> [%u .. %u]", 226 fprintf(stderr, " -> [%u .. %u]",
227 m->mbr.mbr_parts[i].mbrp_start + off, 227 m->mbr.mbr_parts[i].mbrp_start + off,
228 m->mbr.mbr_parts[i].mbrp_size + 228 m->mbr.mbr_parts[i].mbrp_size +
229 m->mbr.mbr_parts[i].mbrp_start + off); 229 m->mbr.mbr_parts[i].mbrp_start + off);
230 } 230 }
231 fprintf(stderr, ",\n"); 231 fprintf(stderr, ",\n");
232 if (m->sector > 0 && i >= 1) 232 if (m->sector > 0 && i >= 1)
233 break; 233 break;
234 } 234 }
235 } while ((m = m->extended)); 235 } while ((m = m->extended));
236} 236}
237#endif 237#endif
238 238
239/* 239/*
240 * Like pread, but handles re-blocking for non 512 byte sector disks 240 * Like pread, but handles re-blocking for non 512 byte sector disks
241 */ 241 */
242static ssize_t 242static ssize_t
243blockread(int fd, size_t secsize, void *buf, size_t nbytes, off_t offset) 243blockread(int fd, size_t secsize, void *buf, size_t nbytes, off_t offset)
244{ 244{
245 ssize_t nr; 245 ssize_t nr;
246 off_t sector = offset / 512; 246 off_t sector = offset / 512;
247 off_t offs = sector * (off_t)secsize; 247 off_t offs = sector * (off_t)secsize;
248 off_t mod = offs & (secsize - 1); 248 off_t mod = offs & (secsize - 1);
249 off_t rnd = offs & ~(secsize - 1); 249 off_t rnd = offs & ~(secsize - 1);
250 char *iobuf; 250 char *iobuf;
251 251
252 assert(nbytes <= 512); 252 assert(nbytes <= 512);
253 253
254 if (secsize == 512) 254 if (secsize == 512)
255 return pread(fd, buf, nbytes, offset); 255 return pread(fd, buf, nbytes, offset);
256 256
257 iobuf = malloc(secsize); 257 iobuf = malloc(secsize);
258 if (iobuf == NULL) 258 if (iobuf == NULL)
259 return -1; 259 return -1;
260 nr = pread(fd, iobuf, secsize, rnd); 260 nr = pread(fd, iobuf, secsize, rnd);
261 if (nr == (off_t)secsize) 261 if (nr == (off_t)secsize)
262 memcpy(buf, &iobuf[mod], nbytes); 262 memcpy(buf, &iobuf[mod], nbytes);
263 free(iobuf); 263 free(iobuf);
264 264
265 return nr == (off_t)secsize ? (off_t)nbytes : -1; 265 return nr == (off_t)secsize ? (off_t)nbytes : -1;
266} 266}
267 267
268/* 268/*
269 * Same for pwrite 269 * Same for pwrite
270 */ 270 */
271static ssize_t 271static ssize_t
272blockwrite(int fd, size_t secsize, const void *buf, size_t nbytes, 272blockwrite(int fd, size_t secsize, const void *buf, size_t nbytes,
273 off_t offset) 273 off_t offset)
274{ 274{
275 ssize_t nr; 275 ssize_t nr;
276 off_t sector = offset / secsize; 276 off_t sector = offset / secsize;
277 off_t offs = sector * (off_t)secsize; 277 off_t offs = sector * (off_t)secsize;
278 off_t mod = offs & (secsize - 1); 278 off_t mod = offs & (secsize - 1);
279 off_t rnd = offs & ~(secsize - 1); 279 off_t rnd = offs & ~(secsize - 1);
280 char *iobuf; 280 char *iobuf;
281 281
282 assert(nbytes <= 512); 282 assert(nbytes <= 512);
283 283
284 if (secsize == 512) 284 if (secsize == 512)
285 return pwrite(fd, buf, nbytes, offset); 285 return pwrite(fd, buf, nbytes, offset);
286 286
287 iobuf = malloc(secsize); 287 iobuf = malloc(secsize);
288 if (iobuf == NULL) 288 if (iobuf == NULL)
289 return -1; 289 return -1;
290 nr = pread(fd, iobuf, secsize, rnd); 290 nr = pread(fd, iobuf, secsize, rnd);
291 if (nr == (off_t)secsize) { 291 if (nr == (off_t)secsize) {
292 memcpy(&iobuf[mod], buf, nbytes); 292 memcpy(&iobuf[mod], buf, nbytes);
293 nr = pwrite(fd, iobuf, secsize, rnd); 293 nr = pwrite(fd, iobuf, secsize, rnd);
294 } 294 }
295 free(iobuf); 295 free(iobuf);
296 296
297 return nr == (off_t)secsize ? (off_t)nbytes : -1; 297 return nr == (off_t)secsize ? (off_t)nbytes : -1;
298} 298}
299 299
300static void 300static void
301free_last_mounted(mbr_info_t *m) 301free_last_mounted(mbr_info_t *m)
302{ 302{
303 size_t i; 303 size_t i;
304 304
305 for (i = 0; i < MBR_PART_COUNT; i++) 305 for (i = 0; i < MBR_PART_COUNT; i++)
306 free(__UNCONST(m->last_mounted[i])); 306 free(__UNCONST(m->last_mounted[i]));
307} 307}
308 308
309static void 309static void
310free_mbr_info(mbr_info_t *m) 310free_mbr_info(mbr_info_t *m)
311{ 311{
312 if (m == NULL) 312 if (m == NULL)
313 return; 313 return;
314 free_last_mounted(m); 314 free_last_mounted(m);
315 free(m); 315 free(m);
316} 316}
317 317
318/* 318/*
319 * To be used only on ports which cannot provide any bios geometry 319 * To be used only on ports which cannot provide any bios geometry
320 */ 320 */
321bool 321bool
322set_bios_geom_with_mbr_guess(struct disk_partitions *parts) 322set_bios_geom_with_mbr_guess(struct disk_partitions *parts)
323{ 323{
324 int cyl, head, sec; 324 int cyl, head, sec;
325 325
326 msg_fmt_display(MSG_nobiosgeom, "%d%d%d", 326 msg_fmt_display(MSG_nobiosgeom, "%d%d%d",
327 pm->dlcyl, pm->dlsec, pm->dlhead); 327 pm->dlcyl, pm->dlsec, pm->dlhead);
328 if (guess_biosgeom_from_parts(parts, &cyl, &head, &sec) >= 0) 328 if (guess_biosgeom_from_parts(parts, &cyl, &head, &sec) >= 0)
329 msg_fmt_display_add(MSG_biosguess, "%d%d%d", cyl, head, sec); 329 msg_fmt_display_add(MSG_biosguess, "%d%d%d", cyl, head, sec);
330 set_bios_geom(parts, &cyl, &head, &sec); 330 set_bios_geom(parts, &cyl, &head, &sec);
331 if (parts->pscheme->change_disk_geom) 331 if (parts->pscheme->change_disk_geom)
332 parts->pscheme->change_disk_geom(parts, cyl, head, sec); 332 parts->pscheme->change_disk_geom(parts, cyl, head, sec);
333 333
334 return edit_outer_parts(parts); 334 return edit_outer_parts(parts);
335} 335}
336 336
337static void 337static void
338mbr_init_chs(struct mbr_disk_partitions *parts, int ncyl, int nhead, int nsec) 338mbr_init_chs(struct mbr_disk_partitions *parts, int ncyl, int nhead, int nsec)
339{ 339{
340 if (ncyl > MAXCYL) 340 if (ncyl > MAXCYL)
341 ncyl = MAXCYL; 341 ncyl = MAXCYL;
342 pm->current_cylsize = nhead*nsec; 342 pm->current_cylsize = nhead*nsec;
343 pm->max_chs = (unsigned long)ncyl*nhead*nsec; 343 pm->max_chs = (unsigned long)ncyl*nhead*nsec;
344 parts->geo_sec = nsec; 344 parts->geo_sec = nsec;
345 parts->geo_head = nhead; 345 parts->geo_head = nhead;
346 parts->geo_cyl = ncyl; 346 parts->geo_cyl = ncyl;
347} 347}
348 348
349/* 349/*
350 * get C/H/S geometry from user via menu interface and 350 * get C/H/S geometry from user via menu interface and
351 * store in globals. 351 * store in globals.
352 */ 352 */
353void 353void
354set_bios_geom(struct disk_partitions *parts, int *cyl, int *head, int *sec) 354set_bios_geom(struct disk_partitions *parts, int *cyl, int *head, int *sec)
355{ 355{
356 char res[80]; 356 char res[80];
357 int bsec, bhead, bcyl; 357 int bsec, bhead, bcyl;
358 daddr_t s; 358 daddr_t s;
359 359
360 if (parts->pscheme->change_disk_geom == NULL) 360 if (parts->pscheme->change_disk_geom == NULL)
361 return; 361 return;
362 362
363 msg_display_add(MSG_setbiosgeom); 363 msg_display_add(MSG_setbiosgeom);
364 364
365 do { 365 do {
366 snprintf(res, 80, "%d", *sec); 366 snprintf(res, 80, "%d", *sec);
367 msg_prompt_add(MSG_sectors, res, res, 80); 367 msg_prompt_add(MSG_sectors, res, res, 80);
368 bsec = atoi(res); 368 bsec = atoi(res);
369 } while (bsec <= 0 || bsec > MAXSECTOR); 369 } while (bsec <= 0 || bsec > MAXSECTOR);
370 370
371 do { 371 do {
372 snprintf(res, 80, "%d", *head); 372 snprintf(res, 80, "%d", *head);
373 msg_prompt_add(MSG_heads, res, res, 80); 373 msg_prompt_add(MSG_heads, res, res, 80);
374 bhead = atoi(res); 374 bhead = atoi(res);
375 } while (bhead <= 0 || bhead > MAXHEAD); 375 } while (bhead <= 0 || bhead > MAXHEAD);
376 s = min(pm->dlsize, mbr_parts.size_limit); 376 s = min(pm->dlsize, mbr_parts.size_limit);
377 bcyl = s / bsec / bhead; 377 bcyl = s / bsec / bhead;
378 if (s != bcyl * bsec * bhead) 378 if (s != bcyl * bsec * bhead)
379 bcyl++; 379 bcyl++;
380 if (bcyl > MAXCYL) 380 if (bcyl > MAXCYL)
381 bcyl = MAXCYL; 381 bcyl = MAXCYL;
382 pm->max_chs = (unsigned long)bcyl * bhead * bsec; 382 pm->max_chs = (unsigned long)bcyl * bhead * bsec;
383 pm->current_cylsize = bhead * bsec; 383 pm->current_cylsize = bhead * bsec;
384 parts->pscheme->change_disk_geom(parts, bcyl, bhead, bsec); 384 parts->pscheme->change_disk_geom(parts, bcyl, bhead, bsec);
385 *cyl = bcyl; 385 *cyl = bcyl;
386 *head = bhead; 386 *head = bhead;
387 *sec = bsec; 387 *sec = bsec;
388} 388}
389 389
390static int 390static int
391find_mbr_space(const struct mbr_info_t *mbrs, uint *start, uint *size, 391find_mbr_space(const struct mbr_info_t *mbrs, uint *start, uint *size,
392 uint from, uint end_of_disk, uint ignore_at, bool primary_only) 392 uint from, uint end_of_disk, uint ignore_at, bool primary_only)
393{ 393{
394 uint sz; 394 uint sz;
395 int i, j; 395 int i, j;
396 uint s, e; 396 uint s, e;
397 const mbr_info_t *m, *me; 397 const mbr_info_t *m, *me;
398 bool is_extended; 398 bool is_extended;
399 399
400 check_again: 400 check_again:
401 m = mbrs; 401 m = mbrs;
402 sz = end_of_disk-from; 402 sz = end_of_disk-from;
403 if (from >= end_of_disk) 403 if (from >= end_of_disk)
404 return -1; 404 return -1;
405 405
406 for (i = 0; i < MBR_PART_COUNT; i++) { 406 for (i = 0; i < MBR_PART_COUNT; i++) {
407 if (m->mbr.mbr_parts[i].mbrp_type == MBR_PTYPE_UNUSED) 407 if (m->mbr.mbr_parts[i].mbrp_type == MBR_PTYPE_UNUSED)
408 continue; 408 continue;
409 409
410 is_extended = MBR_IS_EXTENDED( 410 is_extended = MBR_IS_EXTENDED(
411 m->mbr.mbr_parts[i].mbrp_type); 411 m->mbr.mbr_parts[i].mbrp_type);
412 412
413 s = m->mbr.mbr_parts[i].mbrp_start + m->sector; 413 s = m->mbr.mbr_parts[i].mbrp_start + m->sector;
414 if (s == ignore_at) 414 if (s == ignore_at)
415 continue; 415 continue;
416 e = s + m->mbr.mbr_parts[i].mbrp_size; 416 e = s + m->mbr.mbr_parts[i].mbrp_size;
417 if (s <= from && e > from 417 if (s <= from && e > from
418 && (!is_extended || primary_only)) { 418 && (!is_extended || primary_only)) {
419 if (e - 1 >= end_of_disk) 419 if (e - 1 >= end_of_disk)
420 break; 420 break;
421 if (e >= UINT_MAX) { 421 if (e >= UINT_MAX) {
422 sz = 0; 422 sz = 0;
423 break; 423 break;
424 } 424 }
425 from = e + 1; 425 from = e + 1;
426 goto check_again; 426 goto check_again;
427 } 427 }
428 if (s <= from && e > from && is_extended) { 428 if (s <= from && e > from && is_extended) {
429 /* 429 /*
430 * if we start in the extended partiton, 430 * if we start in the extended partiton,
431 * we must end before its end 431 * we must end before its end
432 */ 432 */
433 sz = e - from; 433 sz = e - from;
434 } 434 }
435 if (s > from && s - from < sz) 435 if (s > from && s - from < sz)
436 sz = s - from; 436 sz = s - from;
437 437
438 if (is_extended) { 438 if (is_extended) {
439 for (me = m->extended; me != NULL; me = me->extended) { 439 for (me = m->extended; me != NULL; me = me->extended) {
440 for (j = 0; j < MBR_PART_COUNT; j++) { 440 for (j = 0; j < MBR_PART_COUNT; j++) {
441 if (me->mbr.mbr_parts[j].mbrp_type == 441 if (me->mbr.mbr_parts[j].mbrp_type ==
442 MBR_PTYPE_UNUSED) 442 MBR_PTYPE_UNUSED)
443 continue; 443 continue;
444 444
445 is_extended = MBR_IS_EXTENDED( 445 is_extended = MBR_IS_EXTENDED(
446 me->mbr.mbr_parts[j].mbrp_type); 446 me->mbr.mbr_parts[j].mbrp_type);
447 447
448 if (is_extended && i > 0) 448 if (is_extended && i > 0)
449 break; 449 break;
450 450
451 s = me->mbr.mbr_parts[j].mbrp_start + 451 s = me->mbr.mbr_parts[j].mbrp_start +
452 me->sector; 452 me->sector;
453 if (s == ignore_at) 453 if (s == ignore_at)
454 continue; 454 continue;
455 e = s + me->mbr.mbr_parts[j].mbrp_size; 455 e = s + me->mbr.mbr_parts[j].mbrp_size;
456 if (me->sector != 0 && me->sector< s) 456 if (me->sector != 0 && me->sector< s)
457 /* 457 /*
458 * can not allow to overwrite 458 * can not allow to overwrite
459 * the ext mbr 459 * the ext mbr
460 */ 460 */
461 s = me->sector; 461 s = me->sector;
462 if (s <= from && e > from) { 462 if (s <= from && e > from) {
463 if (e - 1 >= end_of_disk) 463 if (e - 1 >= end_of_disk)
464 break; 464 break;
465 from = e + 1; 465 from = e + 1;
466 goto check_again; 466 goto check_again;
467 } 467 }
468 if (s > from && s - from < sz) 468 if (s > from && s - from < sz)
469 sz = s - from; 469 sz = s - from;
470 470
471 } 471 }
472 } 472 }
473 } 473 }
474 } 474 }
475 475
476 if (sz == 0) 476 if (sz == 0)
477 return -1; 477 return -1;
478 if (start != NULL) 478 if (start != NULL)
479 *start = from; 479 *start = from;
480 if (size != NULL) 480 if (size != NULL)
481 *size = sz; 481 *size = sz;
482 return 0; 482 return 0;
483} 483}
484 484
485#ifdef BOOTSEL 485#ifdef BOOTSEL
486static int 486static int
487validate_and_set_names(mbr_info_t *mbri, const struct mbr_bootsel *src, 487validate_and_set_names(mbr_info_t *mbri, const struct mbr_bootsel *src,
488 uint32_t ext_base) 488 uint32_t ext_base)
489{ 489{
490 size_t i, l; 490 size_t i, l;
491 const unsigned char *p; 491 const unsigned char *p;
492 492
493 /* 493 /*
494 * The 16 bit magic used to detect whether mbr_bootsel is valid 494 * The 16 bit magic used to detect whether mbr_bootsel is valid
495 * or not is pretty week - collisions have been seen in the wild; 495 * or not is pretty week - collisions have been seen in the wild;
496 * but maybe it is just foreign tools corruption reminiscents 496 * but maybe it is just foreign tools corruption reminiscents
497 * of NetBSD MBRs. Anyway, before accepting a boot menu definition, 497 * of NetBSD MBRs. Anyway, before accepting a boot menu definition,
498 * make sure it is kinda "sane". 498 * make sure it is kinda "sane".
499 */ 499 */
500 500
501 for (i = 0; i < MBR_PART_COUNT; i++) { 501 for (i = 0; i < MBR_PART_COUNT; i++) {
502 /* 502 /*
503 * Make sure the name does not contain controll chars 503 * Make sure the name does not contain controll chars
504 * (not using iscntrl due to minimalistic locale support 504 * (not using iscntrl due to minimalistic locale support
505 * in miniroot environments) and is properly 0-terminated. 505 * in miniroot environments) and is properly 0-terminated.
506 */ 506 */
507 for (l = 0, p = (const unsigned char *)&src->mbrbs_nametab[i]; 507 for (l = 0, p = (const unsigned char *)&src->mbrbs_nametab[i];
508 *p != 0; l++, p++) { 508 *p != 0; l++, p++) {
509 if (l > MBR_BS_PARTNAMESIZE) 509 if (l > MBR_BS_PARTNAMESIZE)
510 return 0; 510 return 0;
511 if (*p < ' ') /* hacky 'iscntrl' */ 511 if (*p < ' ') /* hacky 'iscntrl' */
512 return 0; 512 return 0;
513 } 513 }
514 } 514 }
515 515
516 memcpy(&mbri->mbrb, src, sizeof(*src)); 516 memcpy(&mbri->mbrb, src, sizeof(*src));
517 517
518 if (ext_base == 0) 518 if (ext_base == 0)
519 return mbri->mbrb.mbrbs_defkey - SCAN_1; 519 return mbri->mbrb.mbrbs_defkey - SCAN_1;
520 return 0; 520 return 0;
521} 521}
522#endif 522#endif
523 523
524static int 524static int
525valid_mbr(struct mbr_sector *mbrs) 525valid_mbr(struct mbr_sector *mbrs)
526{ 526{
527 527
528 return (le16toh(mbrs->mbr_magic) == MBR_MAGIC); 528 return (le16toh(mbrs->mbr_magic) == MBR_MAGIC);
529} 529}
530 530
531static int 531static int
532read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri) 532read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri)
533{ 533{
534 struct mbr_partition *mbrp; 534 struct mbr_partition *mbrp;
535 struct mbr_sector *mbrs = &mbri->mbr; 535 struct mbr_sector *mbrs = &mbri->mbr;
536 mbr_info_t *ext = NULL; 536 mbr_info_t *ext = NULL;
537 char diskpath[MAXPATHLEN]; 537 char diskpath[MAXPATHLEN];
538 int fd, i; 538 int fd, i;
539 uint32_t ext_base = 0, next_ext = 0; 539 uint32_t ext_base = 0, next_ext = 0;
540 int rval = -1; 540 int rval = -1;
541#ifdef BOOTSEL 541#ifdef BOOTSEL
542 mbr_info_t *ombri = mbri; 542 mbr_info_t *ombri = mbri;
543 int bootkey = 0; 543 int bootkey = 0;
544#endif 544#endif
545 545
546 memset(mbri, 0, sizeof *mbri); 546 memset(mbri, 0, sizeof *mbri);
547 547
548 /* Open the disk. */ 548 /* Open the disk. */
549 fd = opendisk(disk, O_RDONLY, diskpath, sizeof(diskpath), 0); 549 fd = opendisk(disk, O_RDONLY, diskpath, sizeof(diskpath), 0);
550 if (fd < 0) 550 if (fd < 0)
551 goto bad_mbr; 551 goto bad_mbr;
552 552
553 for (;;) { 553 for (;;) {
554 if (blockread(fd, secsize, mbrs, sizeof *mbrs, 554 if (blockread(fd, secsize, mbrs, sizeof *mbrs,
555 (ext_base + next_ext) * (off_t)MBR_SECSIZE) - sizeof *mbrs != 0) 555 (ext_base + next_ext) * (off_t)MBR_SECSIZE) - sizeof *mbrs != 0)
556 break; 556 break;
557 557
558 if (!valid_mbr(mbrs)) 558 if (!valid_mbr(mbrs))
559 break; 559 break;
560 560
561 mbrp = &mbrs->mbr_parts[0]; 561 mbrp = &mbrs->mbr_parts[0];
562 if (ext_base != 0) { 562 if (ext_base != 0) {
563 /* sanity check extended chain */ 563 /* sanity check extended chain */
564 if (MBR_IS_EXTENDED(mbrp[0].mbrp_type)) 564 if (MBR_IS_EXTENDED(mbrp[0].mbrp_type))
565 break; 565 break;
566 if (mbrp[1].mbrp_type != MBR_PTYPE_UNUSED && 566 if (mbrp[1].mbrp_type != MBR_PTYPE_UNUSED &&
567 !MBR_IS_EXTENDED(mbrp[1].mbrp_type)) 567 !MBR_IS_EXTENDED(mbrp[1].mbrp_type))
568 break; 568 break;
569 if (mbrp[2].mbrp_type != MBR_PTYPE_UNUSED 569 if (mbrp[2].mbrp_type != MBR_PTYPE_UNUSED
570 || mbrp[3].mbrp_type != MBR_PTYPE_UNUSED) 570 || mbrp[3].mbrp_type != MBR_PTYPE_UNUSED)
571 break; 571 break;
572 /* Looks ok, link into extended chain */ 572 /* Looks ok, link into extended chain */
573 mbri->extended = ext; 573 mbri->extended = ext;
574 ext->extended = NULL; 574 ext->extended = NULL;
575 mbri = ext; 575 mbri = ext;
576 ext = NULL; 576 ext = NULL;
577 } 577 }
578#if BOOTSEL 578#if BOOTSEL
579 if (mbrs->mbr_bootsel_magic == htole16(MBR_MAGIC)) { 579 if (mbrs->mbr_bootsel_magic == htole16(MBR_MAGIC)) {
580 /* old bootsel, grab bootsel info */ 580 /* old bootsel, grab bootsel info */
581 bootkey = validate_and_set_names(mbri, 581 bootkey = validate_and_set_names(mbri,
582 (struct mbr_bootsel *) 582 (struct mbr_bootsel *)
583 ((uint8_t *)mbrs + MBR_BS_OLD_OFFSET), 583 ((uint8_t *)mbrs + MBR_BS_OLD_OFFSET),
584 ext_base); 584 ext_base);
585 } else if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) { 585 } else if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) {
586 /* new location */ 586 /* new location */
587 bootkey = validate_and_set_names(mbri, 587 bootkey = validate_and_set_names(mbri,
588 &mbrs->mbr_bootsel, ext_base); 588 &mbrs->mbr_bootsel, ext_base);
589 } 589 }
590 /* Save original flags for mbr code update tests */ 590 /* Save original flags for mbr code update tests */
591 mbri->oflags = mbri->mbrb.mbrbs_flags; 591 mbri->oflags = mbri->mbrb.mbrbs_flags;
592#endif 592#endif
593 mbri->sector = next_ext + ext_base; 593 mbri->sector = next_ext + ext_base;
594 next_ext = 0; 594 next_ext = 0;
595 rval = 0; 595 rval = 0;
596 for (i = 0; i < MBR_PART_COUNT; mbrp++, i++) { 596 for (i = 0; i < MBR_PART_COUNT; mbrp++, i++) {
597 if (mbrp->mbrp_type == MBR_PTYPE_UNUSED) { 597 if (mbrp->mbrp_type == MBR_PTYPE_UNUSED) {
598 /* type is unused, discard scum */ 598 /* type is unused, discard scum */
599 memset(mbrp, 0, sizeof *mbrp); 599 memset(mbrp, 0, sizeof *mbrp);
600 continue; 600 continue;
601 } 601 }
602 mbrp->mbrp_start = le32toh(mbrp->mbrp_start); 602 mbrp->mbrp_start = le32toh(mbrp->mbrp_start);
603 mbrp->mbrp_size = le32toh(mbrp->mbrp_size); 603 mbrp->mbrp_size = le32toh(mbrp->mbrp_size);
604 if (MBR_IS_EXTENDED(mbrp->mbrp_type)) { 604 if (MBR_IS_EXTENDED(mbrp->mbrp_type)) {
605 next_ext = mbrp->mbrp_start; 605 next_ext = mbrp->mbrp_start;
606 } else { 606 } else {
607 uint flags = 0; 607 uint flags = 0;
608 if (mbrp->mbrp_type == MBR_PTYPE_NETBSD) 608 if (mbrp->mbrp_type == MBR_PTYPE_NETBSD)
609 flags |= GLM_LIKELY_FFS; 609 flags |= GLM_LIKELY_FFS;
610 else if (mbrp->mbrp_type == MBR_PTYPE_FAT12 || 610 else if (mbrp->mbrp_type == MBR_PTYPE_FAT12 ||
611 mbrp->mbrp_type == MBR_PTYPE_FAT16S || 611 mbrp->mbrp_type == MBR_PTYPE_FAT16S ||
612 mbrp->mbrp_type == MBR_PTYPE_FAT16B || 612 mbrp->mbrp_type == MBR_PTYPE_FAT16B ||
613 mbrp->mbrp_type == MBR_PTYPE_FAT32 || 613 mbrp->mbrp_type == MBR_PTYPE_FAT32 ||
614 mbrp->mbrp_type == MBR_PTYPE_FAT32L || 614 mbrp->mbrp_type == MBR_PTYPE_FAT32L ||
615 mbrp->mbrp_type == MBR_PTYPE_FAT16L) 615 mbrp->mbrp_type == MBR_PTYPE_FAT16L)
616 flags |= GLM_MAYBE_FAT32; 616 flags |= GLM_MAYBE_FAT32;
617 else if (mbrp->mbrp_type == MBR_PTYPE_NTFS) 617 else if (mbrp->mbrp_type == MBR_PTYPE_NTFS)
618 flags |= GLM_MAYBE_NTFS; 618 flags |= GLM_MAYBE_NTFS;
619 if (flags != 0) { 619 if (flags != 0) {
620 const char *mount = get_last_mounted( 620 const char *mount = get_last_mounted(
621 fd, mbri->sector + mbrp->mbrp_start, 621 fd, mbri->sector + mbrp->mbrp_start,
622 &mbri->fs_type[i], 622 &mbri->fs_type[i],
623 &mbri->fs_sub_type[i], 623 &mbri->fs_sub_type[i],
624 flags); 624 flags);
625 char *p = strdup(mount); 625 char *p = strdup(mount);
626 canonicalize_last_mounted(p); 626 canonicalize_last_mounted(p);
627 mbri->last_mounted[i] = p; 627 mbri->last_mounted[i] = p;
628 } 628 }
629 } 629 }
630#if BOOTSEL 630#if BOOTSEL
631 if (mbri->mbrb.mbrbs_nametab[i][0] != 0 631 if (mbri->mbrb.mbrbs_nametab[i][0] != 0
632 && bootkey-- == 0) 632 && bootkey-- == 0)
633 ombri->bootsec = mbri->sector + 633 ombri->bootsec = mbri->sector +
634 mbrp->mbrp_start; 634 mbrp->mbrp_start;
635#endif 635#endif
636 } 636 }
637 637
638 if (next_ext == 0 || ext_base + next_ext <= mbri->sector) 638 if (next_ext == 0 || ext_base + next_ext <= mbri->sector)
639 break; 639 break;
640 if (ext_base == 0) { 640 if (ext_base == 0) {
641 ext_base = next_ext; 641 ext_base = next_ext;
642 next_ext = 0; 642 next_ext = 0;
643 } 643 }
644 ext = calloc(1, sizeof *ext); 644 ext = calloc(1, sizeof *ext);
645 if (!ext) 645 if (!ext)
646 break; 646 break;
647 mbrs = &ext->mbr; 647 mbrs = &ext->mbr;
648 } 648 }
649 649
650 bad_mbr: 650 bad_mbr:
651 free_mbr_info(ext); 651 free_mbr_info(ext);
652 if (fd >= 0) 652 if (fd >= 0)
653 close(fd); 653 close(fd);
654 if (rval == -1) { 654 if (rval == -1) {
655 memset(&mbrs->mbr_parts, 0, sizeof mbrs->mbr_parts); 655 memset(&mbrs->mbr_parts, 0, sizeof mbrs->mbr_parts);
656 mbrs->mbr_magic = htole16(MBR_MAGIC); 656 mbrs->mbr_magic = htole16(MBR_MAGIC);
657 } 657 }
658 dump_mbr(ombri, "read"); 658 dump_mbr(ombri, "read");
659 return rval; 659 return rval;
660} 660}
661 661
662static int 662static int
663write_mbr(const char *disk, size_t secsize, mbr_info_t *mbri, int bsec, 663write_mbr(const char *disk, size_t secsize, mbr_info_t *mbri, int bsec,
664 int bhead, int bcyl) 664 int bhead, int bcyl)
665{ 665{
666 char diskpath[MAXPATHLEN]; 666 char diskpath[MAXPATHLEN];
667 int fd, i, ret = 0, bits = 0; 667 int fd, i, ret = 0, bits = 0;
668 struct mbr_partition *mbrp; 668 struct mbr_partition *mbrp;
669 u_int32_t pstart, psize; 669 u_int32_t pstart, psize;
670#ifdef BOOTSEL 670#ifdef BOOTSEL
671 struct mbr_sector *mbrs; 671 struct mbr_sector *mbrs;
672#endif 672#endif
673 struct mbr_sector mbrsec; 673 struct mbr_sector mbrsec;
674 mbr_info_t *ext; 674 mbr_info_t *ext;
675 uint sector; 675 uint sector;
676 676
677 dump_mbr(mbri, "write"); 677 dump_mbr(mbri, "write");
678 678
679 /* Open the disk. */ 679 /* Open the disk. */
680 fd = opendisk(disk, secsize == 512 ? O_WRONLY : O_RDWR, 680 fd = opendisk(disk, secsize == 512 ? O_WRONLY : O_RDWR,
681 diskpath, sizeof(diskpath), 0); 681 diskpath, sizeof(diskpath), 0);
682 if (fd < 0) 682 if (fd < 0)
683 return -1; 683 return -1;
684 684
685 /* Remove all wedges */ 685 /* Remove all wedges */
686 if (ioctl(fd, DIOCRMWEDGES, &bits) == -1) 686 if (ioctl(fd, DIOCRMWEDGES, &bits) == -1)
687 return -1; 687 return -1;
688 688
689#ifdef BOOTSEL 689#ifdef BOOTSEL
690 /* 690 /*
691 * If the main boot code (appears to) contain the netbsd bootcode, 691 * If the main boot code (appears to) contain the netbsd bootcode,
692 * copy in all the menu strings and set the default keycode 692 * copy in all the menu strings and set the default keycode
693 * to be that for the default partition. 693 * to be that for the default partition.
694 * Unfortunately we can't rely on the user having actually updated 694 * Unfortunately we can't rely on the user having actually updated
695 * to the new mbr code :-( 695 * to the new mbr code :-(
696 */ 696 */
697 if (mbri->mbr.mbr_bootsel_magic == htole16(MBR_BS_MAGIC) 697 if (mbri->mbr.mbr_bootsel_magic == htole16(MBR_BS_MAGIC)
698 || mbri->mbr.mbr_bootsel_magic == htole16(MBR_MAGIC)) { 698 || mbri->mbr.mbr_bootsel_magic == htole16(MBR_MAGIC)) {
699 int8_t key = SCAN_1; 699 int8_t key = SCAN_1;
700 uint offset = MBR_BS_OFFSET; 700 uint offset = MBR_BS_OFFSET;
701 if (mbri->mbr.mbr_bootsel_magic == htole16(MBR_MAGIC)) 701 if (mbri->mbr.mbr_bootsel_magic == htole16(MBR_MAGIC))
702 offset = MBR_BS_OLD_OFFSET; 702 offset = MBR_BS_OLD_OFFSET;
703 mbri->mbrb.mbrbs_defkey = SCAN_ENTER; 703 mbri->mbrb.mbrbs_defkey = SCAN_ENTER;
704 if (mbri->mbrb.mbrbs_timeo == 0) 704 if (mbri->mbrb.mbrbs_timeo == 0)
705 mbri->mbrb.mbrbs_timeo = 182; /* 10 seconds */ 705 mbri->mbrb.mbrbs_timeo = 182; /* 10 seconds */
706 for (ext = mbri; ext != NULL; ext = ext->extended) { 706 for (ext = mbri; ext != NULL; ext = ext->extended) {
707 mbrs = &ext->mbr; 707 mbrs = &ext->mbr;
708 mbrp = &mbrs->mbr_parts[0]; 708 mbrp = &mbrs->mbr_parts[0];
709 /* Ensure marker is set in each sector */ 709 /* Ensure marker is set in each sector */
710 mbrs->mbr_bootsel_magic = mbri->mbr.mbr_bootsel_magic; 710 mbrs->mbr_bootsel_magic = mbri->mbr.mbr_bootsel_magic;
711 /* and copy in bootsel parameters */ 711 /* and copy in bootsel parameters */
712 *(struct mbr_bootsel *)((uint8_t *)mbrs + offset) = 712 *(struct mbr_bootsel *)((uint8_t *)mbrs + offset) =
713 ext->mbrb; 713 ext->mbrb;
714 for (i = 0; i < MBR_PART_COUNT; i++) { 714 for (i = 0; i < MBR_PART_COUNT; i++) {
715 if (ext->mbrb.mbrbs_nametab[i][0] == 0) 715 if (ext->mbrb.mbrbs_nametab[i][0] == 0)
716 continue; 716 continue;
717 if (ext->sector + mbrp->mbrp_start == 717 if (ext->sector + mbrp->mbrp_start ==
718 mbri->bootsec) 718 mbri->bootsec)
719 mbri->mbrb.mbrbs_defkey = key; 719 mbri->mbrb.mbrbs_defkey = key;
720 key++; 720 key++;
721 } 721 }
722 } 722 }
723 /* copy main data (again) since we've put the 'key' in */ 723 /* copy main data (again) since we've put the 'key' in */
724 *(struct mbr_bootsel *)((uint8_t *)&mbri->mbr + offset) = 724 *(struct mbr_bootsel *)((uint8_t *)&mbri->mbr + offset) =
725 mbri->mbrb; 725 mbri->mbrb;
726 } 726 }
727#endif 727#endif
728 728
729 for (ext = mbri; ext != NULL; ext = ext->extended) { 729 for (ext = mbri; ext != NULL; ext = ext->extended) {
730 memset(mbri->wedge, 0, sizeof mbri->wedge); 730 memset(mbri->wedge, 0, sizeof mbri->wedge);
731 sector = ext->sector; 731 sector = ext->sector;
732 mbrsec = ext->mbr; /* copy sector */ 732 mbrsec = ext->mbr; /* copy sector */
733 mbrp = &mbrsec.mbr_parts[0]; 733 mbrp = &mbrsec.mbr_parts[0];
734 734
735 if (sector != 0 && ext->extended != NULL 735 if (sector != 0 && ext->extended != NULL
736 && ext->extended->mbr.mbr_parts[0].mbrp_type 736 && ext->extended->mbr.mbr_parts[0].mbrp_type
737 == MBR_PTYPE_UNUSED) { 737 == MBR_PTYPE_UNUSED) {
738 738
739 /* 739 /*
740 * This should never happen nowadays, old code 740 * This should never happen nowadays, old code
741 * inserted empty ext sectors in the chain to 741 * inserted empty ext sectors in the chain to
742 * help the gui out - we do not do that anymore. 742 * help the gui out - we do not do that anymore.
743 */ 743 */
744 assert(false); 744 assert(false);
745 745
746 /* We are followed by an empty slot, collapse out */ 746 /* We are followed by an empty slot, collapse out */
747 ext = ext->extended; 747 ext = ext->extended;
748 /* Make us describe the next non-empty partition */ 748 /* Make us describe the next non-empty partition */
749 mbrp[1] = ext->mbr.mbr_parts[1]; 749 mbrp[1] = ext->mbr.mbr_parts[1];
750 } 750 }
751 751
752 for (i = 0; i < MBR_PART_COUNT; i++) { 752 for (i = 0; i < MBR_PART_COUNT; i++) {
753 if (mbrp[i].mbrp_start == 0 && mbrp[i].mbrp_size == 0) { 753 if (mbrp[i].mbrp_start == 0 && mbrp[i].mbrp_size == 0) {
754 mbrp[i].mbrp_scyl = 0; 754 mbrp[i].mbrp_scyl = 0;
755 mbrp[i].mbrp_shd = 0; 755 mbrp[i].mbrp_shd = 0;
756 mbrp[i].mbrp_ssect = 0; 756 mbrp[i].mbrp_ssect = 0;
757 mbrp[i].mbrp_ecyl = 0; 757 mbrp[i].mbrp_ecyl = 0;
758 mbrp[i].mbrp_ehd = 0; 758 mbrp[i].mbrp_ehd = 0;
759 mbrp[i].mbrp_esect = 0; 759 mbrp[i].mbrp_esect = 0;
760 continue; 760 continue;
761 } 761 }
762 pstart = mbrp[i].mbrp_start; 762 pstart = mbrp[i].mbrp_start;
763 psize = mbrp[i].mbrp_size; 763 psize = mbrp[i].mbrp_size;
764 mbrp[i].mbrp_start = htole32(pstart); 764 mbrp[i].mbrp_start = htole32(pstart);
765 mbrp[i].mbrp_size = htole32(psize); 765 mbrp[i].mbrp_size = htole32(psize);
766 if (bsec && bcyl && bhead) { 766 if (bsec && bcyl && bhead) {
767 convert_mbr_chs(bcyl, bhead, bsec, 767 convert_mbr_chs(bcyl, bhead, bsec,
768 &mbrp[i].mbrp_scyl, &mbrp[i].mbrp_shd, 768 &mbrp[i].mbrp_scyl, &mbrp[i].mbrp_shd,
769 &mbrp[i].mbrp_ssect, pstart); 769 &mbrp[i].mbrp_ssect, pstart);
770 convert_mbr_chs(bcyl, bhead, bsec, 770 convert_mbr_chs(bcyl, bhead, bsec,
771 &mbrp[i].mbrp_ecyl, &mbrp[i].mbrp_ehd, 771 &mbrp[i].mbrp_ecyl, &mbrp[i].mbrp_ehd,
772 &mbrp[i].mbrp_esect, pstart + psize - 1); 772 &mbrp[i].mbrp_esect, pstart + psize - 1);
773 } 773 }
774 } 774 }
775 775
776 mbrsec.mbr_magic = htole16(MBR_MAGIC); 776 mbrsec.mbr_magic = htole16(MBR_MAGIC);
777 if (blockwrite(fd, secsize, &mbrsec, sizeof mbrsec, 777 if (blockwrite(fd, secsize, &mbrsec, sizeof mbrsec,
778 sector * (off_t)MBR_SECSIZE) < 0) { 778 sector * (off_t)MBR_SECSIZE) < 0) {
779 ret = -1; 779 ret = -1;
780 break; 780 break;
781 } 781 }
782 } 782 }
783 783
784 (void)close(fd); 784 (void)close(fd);
785 return ret; 785 return ret;
786} 786}
787 787
788static void 788static void
789convert_mbr_chs(int cyl, int head, int sec, 789convert_mbr_chs(int cyl, int head, int sec,
790 uint8_t *cylp, uint8_t *headp, uint8_t *secp, 790 uint8_t *cylp, uint8_t *headp, uint8_t *secp,
791 uint32_t relsecs) 791 uint32_t relsecs)
792{ 792{
793 unsigned int tcyl, temp, thead, tsec; 793 unsigned int tcyl, temp, thead, tsec;
794 794
795 temp = head * sec; 795 temp = head * sec;
796 tcyl = relsecs / temp; 796 tcyl = relsecs / temp;
797 relsecs -= tcyl * temp; 797 relsecs -= tcyl * temp;
798 798
799 thead = relsecs / sec; 799 thead = relsecs / sec;
800 tsec = relsecs - thead * sec + 1; 800 tsec = relsecs - thead * sec + 1;
801 801
802 if (tcyl > MAXCYL) 802 if (tcyl > MAXCYL)
803 tcyl = MAXCYL; 803 tcyl = MAXCYL;
804 804
805 *cylp = MBR_PUT_LSCYL(tcyl); 805 *cylp = MBR_PUT_LSCYL(tcyl);
806 *headp = thead; 806 *headp = thead;
807 *secp = MBR_PUT_MSCYLANDSEC(tcyl, tsec); 807 *secp = MBR_PUT_MSCYLANDSEC(tcyl, tsec);
808} 808}
809 809
810/* 810/*
811 * This function is ONLY to be used as a last resort to provide a 811 * This function is ONLY to be used as a last resort to provide a
812 * hint for the user. Ports should provide a more reliable way 812 * hint for the user. Ports should provide a more reliable way
813 * of getting the BIOS geometry. The i386 code, for example, 813 * of getting the BIOS geometry. The i386 code, for example,
814 * uses the BIOS geometry as passed on from the bootblocks, 814 * uses the BIOS geometry as passed on from the bootblocks,
815 * and only uses this as a hint to the user when that information 815 * and only uses this as a hint to the user when that information
816 * is not present, or a match could not be made with a NetBSD 816 * is not present, or a match could not be made with a NetBSD
817 * device. 817 * device.
818 */ 818 */
819int 819int
820guess_biosgeom_from_parts(struct disk_partitions *parts, 820guess_biosgeom_from_parts(struct disk_partitions *parts,
821 int *cyl, int *head, int *sec) 821 int *cyl, int *head, int *sec)
822{ 822{
823 823
824 /* 824 /*
825 * The physical parameters may be invalid as bios geometry. 825 * The physical parameters may be invalid as bios geometry.
826 * If we cannot determine the actual bios geometry, we are 826 * If we cannot determine the actual bios geometry, we are
827 * better off picking a likely 'faked' geometry than leaving 827 * better off picking a likely 'faked' geometry than leaving
828 * the invalid physical one. 828 * the invalid physical one.
829 */ 829 */
830 830
831 int xcylinders = pm->dlcyl; 831 int xcylinders = pm->dlcyl;
832 int xheads = pm->dlhead; 832 int xheads = pm->dlhead;
833 daddr_t xsectors = pm->dlsec; 833 daddr_t xsectors = pm->dlsec;
834 daddr_t xsize = min(pm->dlsize, mbr_parts.size_limit); 834 daddr_t xsize = min(pm->dlsize, mbr_parts.size_limit);
835 if (xcylinders > MAXCYL || xheads > MAXHEAD || xsectors > MAXSECTOR) { 835 if (xcylinders > MAXCYL || xheads > MAXHEAD || xsectors > MAXSECTOR) {
836 xsectors = MAXSECTOR; 836 xsectors = MAXSECTOR;
837 xheads = MAXHEAD; 837 xheads = MAXHEAD;
838 xcylinders = xsize / (MAXSECTOR * MAXHEAD); 838 xcylinders = xsize / (MAXSECTOR * MAXHEAD);
839 if (xcylinders > MAXCYL) 839 if (xcylinders > MAXCYL)
840 xcylinders = MAXCYL; 840 xcylinders = MAXCYL;
841 } 841 }
842 *cyl = xcylinders; 842 *cyl = xcylinders;
843 *head = xheads; 843 *head = xheads;
844 *sec = xsectors; 844 *sec = xsectors;
845 845
846 if (parts->pscheme->guess_disk_geom == NULL) 846 if (parts->pscheme->guess_disk_geom == NULL)
847 return -1; 847 return -1;
848 848
849 return parts->pscheme->guess_disk_geom(parts, cyl, head, sec); 849 return parts->pscheme->guess_disk_geom(parts, cyl, head, sec);
850} 850}
851 851
852static int 852static int
853mbr_comp_part_entry(const void *a, const void *b) 853mbr_comp_part_entry(const void *a, const void *b)
854{ 854{
855 const struct mbr_partition *part_a = a, 855 const struct mbr_partition *part_a = a,
856 *part_b = b; 856 *part_b = b;
857 857
858 if (part_a->mbrp_type == MBR_PTYPE_UNUSED 858 if (part_a->mbrp_type == MBR_PTYPE_UNUSED
859 && part_b->mbrp_type != MBR_PTYPE_UNUSED) 859 && part_b->mbrp_type != MBR_PTYPE_UNUSED)
860 return 1; 860 return 1;
861 861
862 if (part_b->mbrp_type == MBR_PTYPE_UNUSED 862 if (part_b->mbrp_type == MBR_PTYPE_UNUSED
863 && part_a->mbrp_type != MBR_PTYPE_UNUSED) 863 && part_a->mbrp_type != MBR_PTYPE_UNUSED)
864 return -1; 864 return -1;
865 865
866 return part_a->mbrp_start < part_b->mbrp_start ? -1 : 1; 866 return part_a->mbrp_start < part_b->mbrp_start ? -1 : 1;
867} 867}
868 868
869static void 869static void
870mbr_sort_main_mbr(struct mbr_sector *m) 870mbr_sort_main_mbr(struct mbr_sector *m)
871{ 871{
872 qsort(&m->mbr_parts[0], MBR_PART_COUNT, 872 qsort(&m->mbr_parts[0], MBR_PART_COUNT,
873 sizeof(m->mbr_parts[0]), mbr_comp_part_entry); 873 sizeof(m->mbr_parts[0]), mbr_comp_part_entry);
874} 874}
875 875
876static void 876static void
877mbr_init_default_alignments(struct mbr_disk_partitions *parts, uint track) 877mbr_init_default_alignments(struct mbr_disk_partitions *parts, uint track)
878{ 878{
879 if (track == 0) 879 if (track == 0)
880 track = 16065; 880 track = 16065;
881 881
882 assert(parts->dp.disk_size > 0); 882 assert(parts->dp.disk_size > 0);
883 if (parts->dp.disk_size < 0) 883 if (parts->dp.disk_size < 0)
884 return; 884 return;
885 885
886 /* Use 1MB offset/alignemnt for large (>128GB) disks */ 886 /* Use 1MB offset/alignemnt for large (>128GB) disks */
887 if (parts->dp.disk_size > HUGE_DISK_SIZE) { 887 if (parts->dp.disk_size > HUGE_DISK_SIZE) {
888 parts->ptn_alignment = 2048; 888 parts->ptn_alignment = 2048;
889 parts->ptn_0_offset = 2048; 889 parts->ptn_0_offset = 2048;
890 } else if (parts->dp.disk_size > TINY_DISK_SIZE) { 890 } else if (parts->dp.disk_size > TINY_DISK_SIZE) {
891 parts->ptn_alignment = 64; 891 parts->ptn_alignment = 64;
892 parts->ptn_0_offset = parts->geo_sec; 892 parts->ptn_0_offset = parts->geo_sec;
893 } else { 893 } else {
894 parts->ptn_alignment = 1; 894 parts->ptn_alignment = 1;
895 parts->ptn_0_offset = parts->geo_sec; 895 parts->ptn_0_offset = parts->geo_sec;
896 } 896 }
897 parts->ext_ptn_alignment = track; 897 parts->ext_ptn_alignment = track;
898} 898}
899 899
900static struct disk_partitions * 900static struct disk_partitions *
901mbr_create_new(const char *disk, daddr_t start, daddr_t len, 901mbr_create_new(const char *disk, daddr_t start, daddr_t len,
902 bool is_boot_drive, struct disk_partitions *parent) 902 bool is_boot_drive, struct disk_partitions *parent)
903{ 903{
904 struct mbr_disk_partitions *parts; 904 struct mbr_disk_partitions *parts;
905 struct disk_geom geo; 905 struct disk_geom geo;
906 906
907 assert(start == 0); 907 assert(start == 0);
908 if (start != 0) 908 if (start != 0)
909 return NULL; 909 return NULL;
910 910
911 parts = calloc(1, sizeof(*parts)); 911 parts = calloc(1, sizeof(*parts));
912 if (!parts) 912 if (!parts)
913 return NULL; 913 return NULL;
914 914
915 parts->dp.pscheme = &mbr_parts; 915 parts->dp.pscheme = &mbr_parts;
916 parts->dp.disk = strdup(disk); 916 parts->dp.disk = strdup(disk);
917 if (len > mbr_parts.size_limit) 917 if (len > mbr_parts.size_limit)
918 len = mbr_parts.size_limit; 918 len = mbr_parts.size_limit;
919 parts->dp.disk_start = start; 919 parts->dp.disk_start = start;
920 parts->dp.disk_size = len; 920 parts->dp.disk_size = len;
921 parts->dp.free_space = len-1; 921 parts->dp.free_space = len-1;
922 parts->dp.bytes_per_sector = 512; 922 parts->dp.bytes_per_sector = 512;
923 parts->geo_sec = MAXSECTOR; 923 parts->geo_sec = MAXSECTOR;
924 parts->geo_head = MAXHEAD; 924 parts->geo_head = MAXHEAD;
925 parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1; 925 parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1;
926 926
927 if (get_disk_geom(disk, &geo)) { 927 if (get_disk_geom(disk, &geo)) {
928 parts->geo_sec = geo.dg_nsectors; 928 parts->geo_sec = geo.dg_nsectors;
929 parts->geo_head = geo.dg_ntracks; 929 parts->geo_head = geo.dg_ntracks;
930 parts->geo_cyl = geo.dg_ncylinders; 930 parts->geo_cyl = geo.dg_ncylinders;
931 parts->dp.bytes_per_sector = geo.dg_secsize; 931 parts->dp.bytes_per_sector = geo.dg_secsize;
932 } 932 }
933 933
934 mbr_init_default_alignments(parts, 0); 934 mbr_init_default_alignments(parts, 0);
935 935
936 return &parts->dp; 936 return &parts->dp;
937} 937}
938 938
939static void 939static void
940mbr_calc_free_space(struct mbr_disk_partitions *parts) 940mbr_calc_free_space(struct mbr_disk_partitions *parts)
941{ 941{
942 size_t i; 942 size_t i;
943 mbr_info_t *m; 943 mbr_info_t *m;
944 944
945 parts->dp.free_space = parts->dp.disk_size - 1; 945 parts->dp.free_space = parts->dp.disk_size - 1;
946 parts->dp.num_part = 0; 946 parts->dp.num_part = 0;
947 m = &parts->mbr; 947 m = &parts->mbr;
948 do { 948 do {
949 for (i = 0; i < MBR_PART_COUNT; i++) { 949 for (i = 0; i < MBR_PART_COUNT; i++) {
950 if (m->mbr.mbr_parts[i].mbrp_type == MBR_PTYPE_UNUSED) 950 if (m->mbr.mbr_parts[i].mbrp_type == MBR_PTYPE_UNUSED)
951 continue; 951 continue;
952 952
953 if (m != &parts->mbr && i > 0 && 953 if (m != &parts->mbr && i > 0 &&
954 MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type)) 954 MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type))
955 break; 955 break;
956 956
957 parts->dp.num_part++; 957 parts->dp.num_part++;
958 if (MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type)) 958 if (MBR_IS_EXTENDED(m->mbr.mbr_parts[i].mbrp_type))
959 continue; 959 continue;
960 960
961 daddr_t psize = m->mbr.mbr_parts[i].mbrp_size; 961 daddr_t psize = m->mbr.mbr_parts[i].mbrp_size;
962 if (m != &parts->mbr) 962 if (m != &parts->mbr)
963 psize += m->mbr.mbr_parts[i].mbrp_start; 963 psize += m->mbr.mbr_parts[i].mbrp_start;
964 964
965 if (psize > parts->dp.free_space) 965 if (psize > parts->dp.free_space)
966 parts->dp.free_space = 0; 966 parts->dp.free_space = 0;
967 else 967 else
968 parts->dp.free_space -= psize; 968 parts->dp.free_space -= psize;
969  969
970 } 970 }
971 } while ((m = m->extended)); 971 } while ((m = m->extended));
972} 972}
973 973
974static struct disk_partitions * 974static struct disk_partitions *
975mbr_read_from_disk(const char *disk, daddr_t start, daddr_t len, size_t bps, 975mbr_read_from_disk(const char *disk, daddr_t start, daddr_t len, size_t bps,
976 const struct disk_partitioning_scheme *scheme) 976 const struct disk_partitioning_scheme *scheme)
977{ 977{
978 struct mbr_disk_partitions *parts; 978 struct mbr_disk_partitions *parts;
979 979
980 assert(start == 0); 980 assert(start == 0);
981 if (start != 0) 981 if (start != 0)
982 return NULL; 982 return NULL;
983 983
984 parts = calloc(1, sizeof(*parts)); 984 parts = calloc(1, sizeof(*parts));
985 if (!parts) 985 if (!parts)
986 return NULL; 986 return NULL;
987 987
988 parts->dp.pscheme = scheme; 988 parts->dp.pscheme = scheme;
989 parts->dp.disk = strdup(disk); 989 parts->dp.disk = strdup(disk);
990 if (len >= mbr_parts.size_limit) 990 if (len >= mbr_parts.size_limit)
991 len = mbr_parts.size_limit; 991 len = mbr_parts.size_limit;
992 parts->dp.disk_start = start; 992 parts->dp.disk_start = start;
993 parts->dp.disk_size = len; 993 parts->dp.disk_size = len;
994 parts->geo_sec = MAXSECTOR; 994 parts->geo_sec = MAXSECTOR;
995 parts->geo_head = MAXHEAD; 995 parts->geo_head = MAXHEAD;
996 parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1; 996 parts->geo_cyl = len/MAXHEAD/MAXSECTOR+1;
997 parts->dp.bytes_per_sector = bps; 997 parts->dp.bytes_per_sector = bps;
998 mbr_init_default_alignments(parts, 0); 998 mbr_init_default_alignments(parts, 0);
999 if (read_mbr(disk, parts->dp.bytes_per_sector, &parts->mbr) == -1) { 999 if (read_mbr(disk, parts->dp.bytes_per_sector, &parts->mbr) == -1) {
1000 free(parts); 1000 free(parts);
1001 return NULL; 1001 return NULL;
1002 } 1002 }
1003 mbr_calc_free_space(parts); 1003 mbr_calc_free_space(parts);
1004 if (parts->dp.num_part == 1 && 1004 if (parts->dp.num_part == 1 &&
1005 parts->dp.free_space < parts->ptn_alignment) { 1005 parts->dp.free_space < parts->ptn_alignment) {
1006 struct disk_part_info info; 1006 struct disk_part_info info;
1007 1007
1008 /* 1008 /*
1009 * Check if this is a GPT protective MBR 1009 * Check if this is a GPT protective MBR
1010 */ 1010 */
1011 if (parts->dp.pscheme->get_part_info(&parts->dp, 0, &info) 1011 if (parts->dp.pscheme->get_part_info(&parts->dp, 0, &info)
1012 && info.nat_type != NULL 1012 && info.nat_type != NULL
1013 && mbr_type_from_gen_desc(info.nat_type) == 0xEE) { 1013 && mbr_type_from_gen_desc(info.nat_type) == 0xEE) {
1014 parts->dp.pscheme->free(&parts->dp); 1014 parts->dp.pscheme->free(&parts->dp);
1015 return NULL; 1015 return NULL;
1016 } 1016 }
1017 } 1017 }
1018 1018
1019 return &parts->dp; 1019 return &parts->dp;
1020} 1020}
1021 1021
1022static bool 1022static bool
1023mbr_write_to_disk(struct disk_partitions *new_state) 1023mbr_write_to_disk(struct disk_partitions *new_state)
1024{ 1024{
1025 struct mbr_disk_partitions *parts = 1025 struct mbr_disk_partitions *parts =
1026 (struct mbr_disk_partitions *)new_state; 1026 (struct mbr_disk_partitions *)new_state;
1027 unsigned long bsec, bhead, bcyl; 1027 unsigned long bsec, bhead, bcyl;
1028 daddr_t t; 1028 daddr_t t;
1029 1029
1030 assert(parts->geo_sec != 0); 1030 assert(parts->geo_sec != 0);
1031 if (parts->geo_sec != 0) { 1031 if (parts->geo_sec != 0) {
1032 bsec = parts->geo_sec; 1032 bsec = parts->geo_sec;
1033 bhead = parts->ext_ptn_alignment / bsec; 1033 bhead = parts->ext_ptn_alignment / bsec;
1034 } else { 1034 } else {
1035 bsec = MAXSECTOR; 1035 bsec = MAXSECTOR;
1036 bhead = MAXHEAD; 1036 bhead = MAXHEAD;
1037 } 1037 }
1038 t = bsec * bhead; 1038 t = bsec * bhead;
1039 assert(t != 0); 1039 assert(t != 0);
1040 if ((daddr_t)(1UL<<10) * t <= parts->dp.disk_size) 1040 if ((daddr_t)(1UL<<10) * t <= parts->dp.disk_size)
1041 bcyl = (1UL<<10) - 1; 1041 bcyl = (1UL<<10) - 1;
1042 else 1042 else
1043 bcyl = (unsigned long)(parts->dp.disk_size / t); 1043 bcyl = (unsigned long)(parts->dp.disk_size / t);
1044 1044
1045 return write_mbr(parts->dp.disk, parts->dp.bytes_per_sector, 1045 return write_mbr(parts->dp.disk, parts->dp.bytes_per_sector,
1046 &parts->mbr, bsec, bhead, bcyl) == 0; 1046 &parts->mbr, bsec, bhead, bcyl) == 0;
1047} 1047}
1048 1048
1049static bool 1049static bool
1050mbr_change_disk_geom(struct disk_partitions *arg, int ncyl, int nhead, 1050mbr_change_disk_geom(struct disk_partitions *arg, int ncyl, int nhead,
1051 int nsec) 1051 int nsec)
1052{ 1052{
1053 struct mbr_disk_partitions *parts = (struct mbr_disk_partitions *)arg; 1053 struct mbr_disk_partitions *parts = (struct mbr_disk_partitions *)arg;
1054 daddr_t ptn_0_base, ptn_0_limit; 1054 daddr_t ptn_0_base, ptn_0_limit;
1055 struct disk_part_info info; 1055 struct disk_part_info info;
1056 1056
1057 /* Default to using 'traditional' cylinder alignment */ 1057 /* Default to using 'traditional' cylinder alignment */
1058 mbr_init_chs(parts, ncyl, nhead, nsec); 1058 mbr_init_chs(parts, ncyl, nhead, nsec);
1059 mbr_init_default_alignments(parts, nhead * nsec); 1059 mbr_init_default_alignments(parts, nhead * nsec);
1060 1060
1061 if (parts->dp.disk_size <= TINY_DISK_SIZE) { 1061 if (parts->dp.disk_size <= TINY_DISK_SIZE) {
1062 set_default_sizemult(arg->disk, 1062 set_default_sizemult(arg->disk,
1063 parts->dp.bytes_per_sector, parts->dp.bytes_per_sector); 1063 parts->dp.bytes_per_sector, parts->dp.bytes_per_sector);
1064 return true; 1064 return true;
1065 } 1065 }
1066 1066
1067 if (parts->dp.num_part > 0 && 1067 if (parts->dp.num_part > 0 &&
1068 parts->dp.pscheme->get_part_info(arg, 0, &info)) { 1068 parts->dp.pscheme->get_part_info(arg, 0, &info)) {
1069 1069
1070 /* Try to copy offset of first partition */ 1070 /* Try to copy offset of first partition */
1071 ptn_0_base = info.start; 1071 ptn_0_base = info.start;
1072 ptn_0_limit = info.start + info.size; 1072 ptn_0_limit = info.start + info.size;
1073 if (!(ptn_0_limit & 2047)) { 1073 if (!(ptn_0_limit & 2047)) {
1074 /* Partition ends on a 1MB boundary, align to 1MB */ 1074 /* Partition ends on a 1MB boundary, align to 1MB */
1075 parts->ptn_alignment = 2048; 1075 parts->ptn_alignment = 2048;
1076 if ((ptn_0_base <= 2048 1076 if ((ptn_0_base <= 2048
1077 && !(ptn_0_base & (ptn_0_base - 1))) 1077 && !(ptn_0_base & (ptn_0_base - 1)))
1078 || (ptn_0_base < parts->ptn_0_offset)) { 1078 || (ptn_0_base < parts->ptn_0_offset)) {
1079 /* 1079 /*
1080 * If ptn_base is a power of 2, use it. 1080 * If ptn_base is a power of 2, use it.
1081 * Also use it if the first partition 1081 * Also use it if the first partition
1082 * already is close to the begining 1082 * already is close to the begining
1083 * of the disk and we can't enforce 1083 * of the disk and we can't enforce
1084 * better alignment. 1084 * better alignment.
1085 */ 1085 */
1086 parts->ptn_0_offset = ptn_0_base; 1086 parts->ptn_0_offset = ptn_0_base;
1087 } 1087 }
1088 } 1088 }
1089 } 1089 }
1090 set_default_sizemult(arg->disk, MEG, parts->dp.bytes_per_sector); 1090 set_default_sizemult(arg->disk, MEG, parts->dp.bytes_per_sector);
1091 return true; 1091 return true;
1092} 1092}
1093 1093
1094static size_t 1094static size_t
1095mbr_type_from_gen_desc(const struct part_type_desc *desc) 1095mbr_type_from_gen_desc(const struct part_type_desc *desc)
1096{ 1096{
1097 for (size_t i = 0; i < __arraycount(mbr_gen_type_desc); i++) 1097 for (size_t i = 0; i < __arraycount(mbr_gen_type_desc); i++)
1098 if (&mbr_gen_type_desc[i].gen == desc) 1098 if (&mbr_gen_type_desc[i].gen == desc)
1099 return i; 1099 return i;
1100 1100
1101 return SIZE_T_MAX; 1101 return SIZE_T_MAX;
1102} 1102}
1103 1103
1104static enum part_type 1104static enum part_type
1105mbr_map_part_type(unsigned int t) 1105mbr_map_part_type(unsigned int t)
1106{ 1106{
1107 /* Map some special MBR partition types */ 1107 /* Map some special MBR partition types */
1108 switch (t) { 1108 switch (t) {
1109 case MBR_PTYPE_FAT32: 1109 case MBR_PTYPE_FAT32:
1110 case MBR_PTYPE_FAT32L: 1110 case MBR_PTYPE_FAT32L:
1111 case MBR_PTYPE_FAT16S: 1111 case MBR_PTYPE_FAT16S:
1112 case MBR_PTYPE_FAT16B: 1112 case MBR_PTYPE_FAT16B:
1113 case MBR_PTYPE_FAT16L: 1113 case MBR_PTYPE_FAT16L:
1114 case MBR_PTYPE_FAT12: 1114 case MBR_PTYPE_FAT12:
1115 case MBR_PTYPE_FT_FAT32: 1115 case MBR_PTYPE_FT_FAT32:
1116 case MBR_PTYPE_FT_FAT32_EXT: 1116 case MBR_PTYPE_FT_FAT32_EXT:
1117 return PT_FAT; 1117 return PT_FAT;
1118 case MBR_PTYPE_EFI: 1118 case MBR_PTYPE_EFI:
1119 return PT_EFI_SYSTEM; 1119 return PT_EFI_SYSTEM;
1120 case MBR_PTYPE_NETBSD: 1120 case MBR_PTYPE_NETBSD:
1121 return PT_root; 1121 return PT_root;
1122 } 1122 }
1123 1123
1124 return PT_unknown; 1124 return PT_unknown;
1125} 1125}
1126 1126
1127static void 1127static void
1128map_mbr_part_types(void) 1128map_mbr_part_types(void)
1129{ 1129{
1130 1130
1131 for (size_t i = 0; i < __arraycount(mbr_part_types_src); i++) { 1131 for (size_t i = 0; i < __arraycount(mbr_part_types_src); i++) {
1132 unsigned int v = mbr_part_types_src[i].ptype; 1132 unsigned int v = mbr_part_types_src[i].ptype;
1133 1133
1134 snprintf(mbr_gen_type_desc[v].short_buf, 1134 snprintf(mbr_gen_type_desc[v].short_buf,
1135 sizeof(mbr_gen_type_desc[v].short_buf), "%u", v); 1135 sizeof(mbr_gen_type_desc[v].short_buf), "%u", v);
1136 mbr_gen_type_desc[v].gen.short_desc = 1136 mbr_gen_type_desc[v].gen.short_desc =
1137 mbr_gen_type_desc[v].short_buf; 1137 mbr_gen_type_desc[v].short_buf;
1138 mbr_gen_type_desc[v].gen.description = 1138 mbr_gen_type_desc[v].gen.description =
1139 mbr_part_types_src[i].desc; 1139 mbr_part_types_src[i].desc;
1140 mbr_gen_type_desc[v].gen.generic_ptype = mbr_map_part_type(v); 1140 mbr_gen_type_desc[v].gen.generic_ptype = mbr_map_part_type(v);
1141 mbr_gen_type_desc[v].next_ptype = ~0U; 1141 mbr_gen_type_desc[v].next_ptype = ~0U;
1142 mbr_gen_type_desc[last_added_part_type].next_ptype = v; 1142 mbr_gen_type_desc[last_added_part_type].next_ptype = v;
1143 known_part_types++; 1143 known_part_types++;
1144 last_added_part_type = v; 1144 last_added_part_type = v;
1145 } 1145 }
1146} 1146}

cvs diff -r1.4 -r1.5 src/usr.sbin/sysinst/mbr.h (switch to unified diff)

--- src/usr.sbin/sysinst/mbr.h 2019/11/12 16:33:14 1.4
+++ src/usr.sbin/sysinst/mbr.h 2020/04/22 23:43:12 1.5
@@ -1,138 +1,138 @@ @@ -1,138 +1,138 @@
1/* $NetBSD: mbr.h,v 1.4 2019/11/12 16:33:14 martin Exp $ */ 1/* $NetBSD: mbr.h,v 1.5 2020/04/22 23:43:12 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright 1997, 1988 Piermont Information Systems Inc. 4 * Copyright 1997, 1988 Piermont Information Systems Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Philip A. Nelson for Piermont Information Systems Inc. 7 * Written by Philip A. Nelson for Piermont Information Systems Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse 17 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
18 * or promote products derived from this software without specific prior 18 * or promote products derived from this software without specific prior
19 * written permission. 19 * written permission.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS'' 21 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE 24 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE. 31 * THE POSSIBILITY OF SUCH DAMAGE.
32 * 32 *
33 */ 33 */
34 34
35#ifndef _MBR_H 35#ifndef _MBR_H
36#define _MBR_H 36#define _MBR_H
37 37
38/* 38/*
39 * mbr.h -- definitions for reading, writing and editing DOS MBRs. 39 * mbr.h -- definitions for reading, writing and editing DOS MBRs.
40 * Use by including from md.h on ports which use MBRs (i386, powerpc, arc) 40 * Use by including from md.h on ports which use MBRs (i386, powerpc, arc)
41 * naming convention: dlxxxx => NetBSD disklabel, bxxxx => bios 41 * naming convention: dlxxxx => NetBSD disklabel, bxxxx => bios
42 */ 42 */
43 43
44/* constants and defines */ 44/* constants and defines */
45 45
46#include <sys/bootblock.h> 46#include <sys/bootblock.h>
47 47
48/* 48/*
49 * XXX I (dsl) haven't the foggiest idea what the MBR extended chain 49 * XXX I (dsl) haven't the foggiest idea what the MBR extended chain
50 * looks like if the sector size isn't 512. 50 * looks like if the sector size isn't 512.
51 */ 51 */
52#define MBR_SECSIZE 512 52#define MBR_SECSIZE 512
53 53
54#define MBR_PUT_LSCYL(c) ((c) & 0xff) 54#define MBR_PUT_LSCYL(c) ((c) & 0xff)
55#define MBR_PUT_MSCYLANDSEC(c,s) (((s) & 0x3f) | (((c) >> 2) & 0xc0)) 55#define MBR_PUT_MSCYLANDSEC(c,s) (((s) & 0x3f) | (((c) >> 2) & 0xc0))
56 56
57#define MBR_DEV_LEN 16 /* for wedge names */ 57#define MBR_DEV_LEN 16 /* for wedge names */
58 58
59typedef struct mbr_info_t mbr_info_t; 59typedef struct mbr_info_t mbr_info_t;
60struct mbr_info_t { 60struct mbr_info_t {
61 struct mbr_sector mbr; 61 struct mbr_sector mbr;
62#ifdef BOOTSEL 62#ifdef BOOTSEL
63 struct mbr_bootsel mbrb; /* writeable for any mbr code */ 63 struct mbr_bootsel mbrb; /* writeable for any mbr code */
64 uint oflags; 64 uint oflags;
65#endif 65#endif
66 uint sector; /* where we read this from */ 66 uint sector; /* where we read this from */
67 mbr_info_t *extended; /* next in extended partition list */ 67 mbr_info_t *extended; /* next in extended partition list */
68 const char *last_mounted[MBR_PART_COUNT]; 68 const char *last_mounted[MBR_PART_COUNT];
69 uint fs_type[MBR_PART_COUNT], fs_sub_type[MBR_PART_COUNT]; 69 uint fs_type[MBR_PART_COUNT], fs_sub_type[MBR_PART_COUNT];
70#ifdef BOOTSEL 70#ifdef BOOTSEL
71 /* only in first item... */ 71 /* only in first item... */
72 uint bootsec; /* start sector of bootmenu default */ 72 uint bootsec; /* start sector of bootmenu default */
73#endif 73#endif
74 /* for temporary access */ 74 /* for temporary access */
75 char wedge[MBR_PART_COUNT][MBR_DEV_LEN]; 75 char wedge[MBR_PART_COUNT][MBR_DEV_LEN];
76}; 76};
77 77
78#ifdef BOOTSEL 78#ifdef BOOTSEL
79struct mbr_bootsel *mbs; 79extern struct mbr_bootsel *mbs;
80 80
81 /* sync with src/sbin/fdisk/fdisk.c */ 81 /* sync with src/sbin/fdisk/fdisk.c */
82#define DEFAULT_BOOTDIR "/usr/mdec" 82#define DEFAULT_BOOTDIR "/usr/mdec"
83#define DEFAULT_BOOTCODE "mbr" 83#define DEFAULT_BOOTCODE "mbr"
84#define DEFAULT_BOOTSELCODE "mbr_bootsel" 84#define DEFAULT_BOOTSELCODE "mbr_bootsel"
85#define DEFAULT_BOOTEXTCODE "mbr_ext" 85#define DEFAULT_BOOTEXTCODE "mbr_ext"
86 86
87/* Scan values for the various keys we use, as returned by the BIOS */ 87/* Scan values for the various keys we use, as returned by the BIOS */
88#define SCAN_ENTER 0x1c 88#define SCAN_ENTER 0x1c
89#define SCAN_F1 0x3b 89#define SCAN_F1 0x3b
90#define SCAN_1 0x2 90#define SCAN_1 0x2
91 91
92#endif /* BOOTSEL */ 92#endif /* BOOTSEL */
93 93
94/* from mbr.c */ 94/* from mbr.c */
95void set_fdisk_geom(void); /* edit incore BIOS geometry */ 95void set_fdisk_geom(void); /* edit incore BIOS geometry */
96void disp_cur_geom(void); 96void disp_cur_geom(void);
97int check_geom(void); /* primitive geometry sanity-check */ 97int check_geom(void); /* primitive geometry sanity-check */
98 98
99void disp_cur_part(struct mbr_partition *, int, int); 99void disp_cur_part(struct mbr_partition *, int, int);
100int partsoverlap(struct mbr_partition *, int, int); 100int partsoverlap(struct mbr_partition *, int, int);
101 101
102/* from mbr.c */ 102/* from mbr.c */
103 103
104int guess_biosgeom_from_parts(struct disk_partitions*, int *, int *, int *); 104int guess_biosgeom_from_parts(struct disk_partitions*, int *, int *, int *);
105bool set_bios_geom_with_mbr_guess(struct disk_partitions*); 105bool set_bios_geom_with_mbr_guess(struct disk_partitions*);
106void set_bios_geom(struct disk_partitions *, int *cyl, int *head, int *sec); 106void set_bios_geom(struct disk_partitions *, int *cyl, int *head, int *sec);
107int otherpart(int); 107int otherpart(int);
108int ourpart(int); 108int ourpart(int);
109void edit_ptn_bounds(void); 109void edit_ptn_bounds(void);
110#ifdef BOOTSEL 110#ifdef BOOTSEL
111void disp_bootsel(void); 111void disp_bootsel(void);
112void edit_bootsel_entry(int); 112void edit_bootsel_entry(int);
113void edit_bootsel_timeout(void); 113void edit_bootsel_timeout(void);
114void edit_bootsel_default_ptn(int); 114void edit_bootsel_default_ptn(int);
115void edit_bootsel_default_disk(int); 115void edit_bootsel_default_disk(int);
116void configure_bootsel(void); 116void configure_bootsel(void);
117#endif 117#endif
118 118
119/* 119/*
120 * MBR specific: check if the chosen partitioning will work 120 * MBR specific: check if the chosen partitioning will work
121 * and perform any MD queries/fixup. 121 * and perform any MD queries/fixup.
122 * With quiet = true, try to avoid user interaction and 122 * With quiet = true, try to avoid user interaction and
123 * never return 1. 123 * never return 1.
124 * 124 *
125 * Return value: 125 * Return value:
126 * 0 -> abort 126 * 0 -> abort
127 * 1 -> re-edit 127 * 1 -> re-edit
128 * 2 -> continue installation 128 * 2 -> continue installation
129*/ 129*/
130int md_check_mbr(struct disk_partitions*, mbr_info_t*, bool quiet); 130int md_check_mbr(struct disk_partitions*, mbr_info_t*, bool quiet);
131 131
132/* 132/*
133 * Called early during updates (before md_pre_update), 133 * Called early during updates (before md_pre_update),
134 * returns true if partitions have been modified. 134 * returns true if partitions have been modified.
135 */ 135 */
136bool md_mbr_update_check(struct disk_partitions*, mbr_info_t*); 136bool md_mbr_update_check(struct disk_partitions*, mbr_info_t*);
137 137
138#endif 138#endif