Don't depend on common symbol definitions.diff -r1.57 -r1.58 src/usr.sbin/sysinst/defs.h
(joerg)
--- 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 | |||
46 | const char *getfslabelname(uint, uint); | 46 | const 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 */ | |
106 | enum layout_type { LY_KEEPEXISTING, LY_SETSIZES, LY_USEDEFAULT, LY_USEFULL }; | 106 | enum layout_type { LY_KEEPEXISTING, LY_SETSIZES, LY_USEDEFAULT, LY_USEFULL }; | |
107 | enum setup_type { SY_NEWRAID, SY_NEWCGD, SY_NEWLVM }; | 107 | enum setup_type { SY_NEWRAID, SY_NEWCGD, SY_NEWLVM }; | |
108 | 108 | |||
109 | /* Installation sets */ | 109 | /* Installation sets */ | |
110 | enum { | 110 | enum { | |
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 */ | |
216 | typedef struct arg_rv { | 216 | typedef 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 | */ | |
224 | typedef struct arg_replace { | 224 | typedef 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 | */ | |
233 | typedef struct arg_rep_int { | 233 | typedef 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 | |||
238 | typedef struct distinfo { | 238 | typedef 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 | */ | |
255 | struct part_usage_info { | 255 | struct 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 | */ | |
319 | struct partition_usage_set { | 319 | struct 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 | */ | |
333 | struct single_part_fs_edit { | 333 | struct 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 | */ | |
355 | struct install_partition_desc { | 355 | struct 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 | |||
363 | int debug; /* set by -D option */ | 363 | extern int debug; /* set by -D option */ | |
364 | 364 | |||
365 | char machine[SSTRSIZE]; | 365 | extern char machine[SSTRSIZE]; | |
366 | 366 | |||
367 | int ignorerror; | 367 | extern int ignorerror; | |
368 | int ttysig_ignore; | 368 | extern int ttysig_ignore; | |
369 | pid_t ttysig_forward; | 369 | extern pid_t ttysig_forward; | |
370 | uint sizemult; | 370 | extern uint sizemult; | |
371 | extern const char *multname; | 371 | extern const char *multname; | |
372 | extern const char *err_outofmem; | 372 | extern const char *err_outofmem; | |
373 | int partman_go; /* run extended partition manager */ | 373 | extern int partman_go; /* run extended partition manager */ | |
374 | 374 | |||
375 | /* logging variables */ | 375 | /* logging variables */ | |
376 | 376 | |||
377 | FILE *logfp; | 377 | extern FILE *logfp; | |
378 | FILE *script; | 378 | extern FILE *script; | |
379 | 379 | |||
380 | #define MAX_DISKS 15 | 380 | #define MAX_DISKS 15 | |
381 | 381 | |||
382 | daddr_t root_limit; /* BIOS (etc) read limit */ | 382 | extern daddr_t root_limit; /* BIOS (etc) read limit */ | |
383 | 383 | |||
384 | enum SHRED_T { SHRED_NONE=0, SHRED_ZEROS, SHRED_RANDOM }; | 384 | enum 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 */ | |
387 | SLIST_HEAD(pm_head_t, pm_devs) pm_head; | 387 | extern SLIST_HEAD(pm_head_t, pm_devs) pm_head; | |
388 | 388 | |||
389 | struct pm_devs { | 389 | struct 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 | }; | |
456 | struct pm_devs *pm; /* Pointer to current device with which we work */ | 456 | extern struct pm_devs *pm; /* Pointer to current device with which we work */ | |
457 | struct pm_devs *pm_new; /* Pointer for next allocating device in find_disks() */ | 457 | extern 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 */ | |
460 | struct part_entry { | 460 | struct 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. */ | |
472 | char xfer_dir[STRSIZE]; | 472 | extern char xfer_dir[STRSIZE]; | |
473 | int clean_xfer_dir; | 473 | extern 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 */ | |
533 | char ext_dir_bin[STRSIZE]; | 533 | extern char ext_dir_bin[STRSIZE]; | |
534 | 534 | |||
535 | /* Abs. path we extract source sets from */ | 535 | /* Abs. path we extract source sets from */ | |
536 | char ext_dir_src[STRSIZE]; | 536 | extern char ext_dir_src[STRSIZE]; | |
537 | 537 | |||
538 | /* Abs. path we extract pkgsrc from */ | 538 | /* Abs. path we extract pkgsrc from */ | |
539 | char ext_dir_pkgsrc[STRSIZE]; | 539 | extern 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 */ | |
542 | char set_dir_bin[STRSIZE]; | 542 | extern 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 */ | |
545 | char set_dir_src[STRSIZE]; | 545 | extern 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 */ | |
548 | char pkg_dir[STRSIZE]; | 548 | extern 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 */ | |
551 | char pkgsrc_dir[STRSIZE]; | 551 | extern char pkgsrc_dir[STRSIZE]; | |
552 | 552 | |||
553 | /* User shell */ | 553 | /* User shell */ | |
554 | const char *ushell; | 554 | extern 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 | |||
560 | struct ftpinfo { | 560 | struct 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 */ | |
570 | struct ftpinfo ftp, pkg, pkgsrc; | 570 | extern struct ftpinfo ftp, pkg, pkgsrc; | |
571 | 571 | |||
572 | int (*fetch_fn)(const char *); | 572 | extern int (*fetch_fn)(const char *); | |
573 | char nfs_host[STRSIZE]; | 573 | extern char nfs_host[STRSIZE]; | |
574 | char nfs_dir[STRSIZE]; | 574 | extern char nfs_dir[STRSIZE]; | |
575 | 575 | |||
576 | char cdrom_dev[SSTRSIZE]; /* Typically "cd0a" */ | 576 | extern char cdrom_dev[SSTRSIZE]; /* Typically "cd0a" */ | |
577 | char fd_dev[SSTRSIZE]; /* Typically "/dev/fd0a" */ | 577 | extern char fd_dev[SSTRSIZE]; /* Typically "/dev/fd0a" */ | |
578 | const char *fd_type; /* "msdos", "ffs" or maybe "ados" */ | 578 | extern const char *fd_type; /* "msdos", "ffs" or maybe "ados" */ | |
579 | 579 | |||
580 | char localfs_dev[SSTRSIZE]; | 580 | extern char localfs_dev[SSTRSIZE]; | |
581 | char localfs_fs[SSTRSIZE]; | 581 | extern char localfs_fs[SSTRSIZE]; | |
582 | char localfs_dir[STRSIZE]; | 582 | extern char localfs_dir[STRSIZE]; | |
583 | 583 | |||
584 | char targetroot_mnt[SSTRSIZE]; | 584 | extern char targetroot_mnt[SSTRSIZE]; | |
585 | 585 | |||
586 | int mnt2_mounted; | 586 | extern int mnt2_mounted; | |
587 | 587 | |||
588 | char dist_postfix[SSTRSIZE]; | 588 | extern char dist_postfix[SSTRSIZE]; | |
589 | char dist_tgz_postfix[SSTRSIZE]; | 589 | extern char dist_tgz_postfix[SSTRSIZE]; | |
590 | 590 | |||
591 | /* needed prototypes */ | 591 | /* needed prototypes */ | |
592 | void set_menu_numopts(int, int); | 592 | void set_menu_numopts(int, int); | |
593 | void remove_color_options(void); | 593 | void remove_color_options(void); | |
594 | void remove_raid_options(void); | 594 | void remove_raid_options(void); | |
595 | void remove_lvm_options(void); | 595 | void remove_lvm_options(void); | |
596 | void remove_cgd_options(void); | 596 | void remove_cgd_options(void); | |
597 | 597 | |||
598 | /* Machine dependent functions .... */ | 598 | /* Machine dependent functions .... */ | |
599 | void md_init(void); | 599 | void md_init(void); | |
600 | void md_init_set_status(int); /* SFLAG_foo */ | 600 | void 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 */ | |
603 | bool md_get_info(struct install_partition_desc*); | 603 | bool md_get_info(struct install_partition_desc*); | |
604 | bool md_make_bsd_partitions(struct install_partition_desc*); | 604 | bool md_make_bsd_partitions(struct install_partition_desc*); | |
605 | bool md_check_partitions(struct install_partition_desc*); | 605 | bool 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 | */ | |
611 | bool md_gpt_post_write(struct disk_partitions*, part_id root_id, | 611 | bool 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 | */ | |
620 | bool md_pre_disklabel(struct install_partition_desc*, struct disk_partitions*); | 620 | bool md_pre_disklabel(struct install_partition_desc*, struct disk_partitions*); | |
621 | bool md_post_disklabel(struct install_partition_desc*, struct disk_partitions*); | 621 | bool md_post_disklabel(struct install_partition_desc*, struct disk_partitions*); | |
622 | int md_pre_mount(struct install_partition_desc*, size_t); | 622 | int md_pre_mount(struct install_partition_desc*, size_t); | |
623 | int md_post_newfs(struct install_partition_desc*); | 623 | int md_post_newfs(struct install_partition_desc*); | |
624 | int md_post_extract(struct install_partition_desc*); | 624 | int md_post_extract(struct install_partition_desc*); | |
625 | void md_cleanup_install(struct install_partition_desc*); | 625 | void 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 */ | |
628 | int md_pre_update(struct install_partition_desc*); | 628 | int md_pre_update(struct install_partition_desc*); | |
629 | int md_update(struct install_partition_desc*); | 629 | int 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 */ | |
633 | void toplevel(void); | 633 | void toplevel(void); | |
634 | 634 | |||
635 | /* from disks.c */ | 635 | /* from disks.c */ | |
636 | bool get_default_cdrom(char *, size_t); | 636 | bool get_default_cdrom(char *, size_t); | |
637 | int find_disks(const char *, bool); | 637 | int find_disks(const char *, bool); | |
638 | bool enumerate_disks(void *state,bool (*func)(void *state, const char *dev)); | 638 | bool enumerate_disks(void *state,bool (*func)(void *state, const char *dev)); | |
639 | bool is_cdrom_device(const char *dev, bool as_target); | 639 | bool is_cdrom_device(const char *dev, bool as_target); | |
640 | bool is_bootable_device(const char *dev); | 640 | bool is_bootable_device(const char *dev); | |
641 | bool is_partitionable_device(const char *dev); | 641 | bool is_partitionable_device(const char *dev); | |
642 | bool convert_scheme(struct pm_devs *p, bool is_boot_drive, const char **err_msg); | 642 | bool 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) */ | |
646 | struct selected_partition { | 646 | struct selected_partition { | |
647 | struct disk_partitions *parts; | 647 | struct disk_partitions *parts; | |
648 | part_id id; | 648 | part_id id; | |
649 | }; | 649 | }; | |
650 | struct selected_partitions { | 650 | struct 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 | }; | |
656 | bool select_partitions(struct selected_partitions *res, | 656 | bool select_partitions(struct selected_partitions *res, | |
657 | const struct disk_partitions *ignore); | 657 | const struct disk_partitions *ignore); | |
658 | daddr_t selected_parts_size(struct selected_partitions *); | 658 | daddr_t selected_parts_size(struct selected_partitions *); | |
659 | void free_selected_partitions(struct selected_partitions *); | 659 | void free_selected_partitions(struct selected_partitions *); | |
660 | 660 | |||
661 | struct clone_target_menu_data { | 661 | struct 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 | |||
666 | int clone_target_select(menudesc *m, void *arg); | 666 | int clone_target_select(menudesc *m, void *arg); | |
667 | bool clone_partition_data(struct disk_partitions *dest_parts, part_id did, | 667 | bool 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 | |||
671 | struct menudesc; | 671 | struct menudesc; | |
672 | void disp_cur_fspart(int, int); | 672 | void disp_cur_fspart(int, int); | |
673 | int make_filesystems(struct install_partition_desc *); | 673 | int make_filesystems(struct install_partition_desc *); | |
674 | int make_fstab(struct install_partition_desc *); | 674 | int make_fstab(struct install_partition_desc *); | |
675 | int mount_disks(struct install_partition_desc *); | 675 | int mount_disks(struct install_partition_desc *); | |
676 | int set_swap_if_low_ram(struct install_partition_desc *); | 676 | int set_swap_if_low_ram(struct install_partition_desc *); | |
677 | int set_swap(struct install_partition_desc *); | 677 | int set_swap(struct install_partition_desc *); | |
678 | int check_swap(const char *, int); | 678 | int check_swap(const char *, int); | |
679 | char *bootxx_name(struct install_partition_desc *); | 679 | char *bootxx_name(struct install_partition_desc *); | |
680 | int get_dkwedges(struct dkwedge_info **, const char *); | 680 | int get_dkwedges(struct dkwedge_info **, const char *); | |
681 | 681 | |||
682 | /* from disks_lfs.c */ | 682 | /* from disks_lfs.c */ | |
683 | int fs_is_lfs(void *); | 683 | int 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 | */ | |
711 | const char *get_last_mounted(int fd, daddr_t offset, uint *fs_type, | 711 | const 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); | |
713 | void canonicalize_last_mounted(char*); | 713 | void canonicalize_last_mounted(char*); | |
714 | int edit_and_check_label(struct pm_devs *p, struct partition_usage_set *pset, bool install); | 714 | int edit_and_check_label(struct pm_devs *p, struct partition_usage_set *pset, bool install); | |
715 | int edit_ptn(menudesc *, void *); | 715 | int edit_ptn(menudesc *, void *); | |
716 | int checkoverlap(struct disk_partitions *parts); | 716 | int checkoverlap(struct disk_partitions *parts); | |
717 | daddr_t getpartsize(struct disk_partitions *parts, daddr_t partstart, | 717 | daddr_t getpartsize(struct disk_partitions *parts, daddr_t partstart, | |
718 | daddr_t defpartsize); | 718 | daddr_t defpartsize); | |
719 | daddr_t getpartoff(struct disk_partitions *parts, daddr_t defpartstart); | 719 | daddr_t getpartoff(struct disk_partitions *parts, daddr_t defpartstart); | |
720 | 720 | |||
721 | /* from install.c */ | 721 | /* from install.c */ | |
722 | void do_install(void); | 722 | void do_install(void); | |
723 | 723 | |||
724 | /* from factor.c */ | 724 | /* from factor.c */ | |
725 | void factor(long, long *, int, int *); | 725 | void factor(long, long *, int, int *); | |
726 | 726 | |||
727 | /* from fdisk.c */ | 727 | /* from fdisk.c */ | |
728 | void get_disk_info(char *); | 728 | void get_disk_info(char *); | |
729 | void set_disk_info(char *); | 729 | void set_disk_info(char *); | |
730 | 730 | |||
731 | /* from geom.c */ | 731 | /* from geom.c */ | |
732 | bool disk_ioctl(const char *, unsigned long, void *); | 732 | bool disk_ioctl(const char *, unsigned long, void *); | |
733 | bool get_wedge_list(const char *, struct dkwedge_list *); | 733 | bool get_wedge_list(const char *, struct dkwedge_list *); | |
734 | bool get_wedge_info(const char *, struct dkwedge_info *); | 734 | bool get_wedge_info(const char *, struct dkwedge_info *); | |
735 | bool get_disk_geom(const char *, struct disk_geom *); | 735 | bool get_disk_geom(const char *, struct disk_geom *); | |
736 | bool get_label_geom(const char *, struct disklabel *); | 736 | bool get_label_geom(const char *, struct disklabel *); | |
737 | 737 | |||
738 | /* from net.c */ | 738 | /* from net.c */ | |
739 | extern int network_up; | 739 | extern int network_up; | |
740 | extern char net_namesvr[STRSIZE]; | 740 | extern char net_namesvr[STRSIZE]; | |
741 | int get_via_ftp(unsigned int); | 741 | int get_via_ftp(unsigned int); | |
742 | int get_via_nfs(void); | 742 | int get_via_nfs(void); | |
743 | int config_network(void); | 743 | int config_network(void); | |
744 | void mnt_net_config(void); | 744 | void mnt_net_config(void); | |
745 | void make_url(char *, struct ftpinfo *, const char *); | 745 | void make_url(char *, struct ftpinfo *, const char *); | |
746 | int get_pkgsrc(void); | 746 | int get_pkgsrc(void); | |
747 | const char *url_proto(unsigned int); | 747 | const char *url_proto(unsigned int); | |
748 | 748 | |||
749 | /* From run.c */ | 749 | /* From run.c */ | |
750 | int collect(int, char **, const char *, ...) __printflike(3, 4); | 750 | int collect(int, char **, const char *, ...) __printflike(3, 4); | |
751 | int run_program(int, const char *, ...) __printflike(2, 3); | 751 | int run_program(int, const char *, ...) __printflike(2, 3); | |
752 | void do_logging(void); | 752 | void do_logging(void); | |
753 | int do_system(const char *); | 753 | int do_system(const char *); | |
754 | 754 | |||
755 | /* from upgrade.c */ | 755 | /* from upgrade.c */ | |
756 | void do_upgrade(void); | 756 | void do_upgrade(void); | |
757 | void do_reinstall_sets(void); | 757 | void do_reinstall_sets(void); | |
758 | void restore_etc(void); | 758 | void restore_etc(void); | |
759 | 759 | |||
760 | /* from part_edit.c */ | 760 | /* from part_edit.c */ | |
761 | int err_msg_win(const char*); | 761 | int err_msg_win(const char*); | |
762 | const struct disk_partitioning_scheme *select_part_scheme(struct pm_devs *dev, | 762 | const 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); | |
765 | bool edit_outer_parts(struct disk_partitions*); | 765 | bool edit_outer_parts(struct disk_partitions*); | |
766 | bool parts_use_wholedisk(struct disk_partitions*, | 766 | bool 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 | */ | |
774 | bool md_parts_use_wholedisk(struct disk_partitions*); | 774 | bool md_parts_use_wholedisk(struct disk_partitions*); | |
775 | 775 | |||
776 | /* from util.c */ | 776 | /* from util.c */ | |
777 | bool root_is_read_only(void); | 777 | bool root_is_read_only(void); | |
778 | void get_ptn_alignment(const struct disk_partitions *parts, daddr_t *align, daddr_t *p0off); | 778 | void get_ptn_alignment(const struct disk_partitions *parts, daddr_t *align, daddr_t *p0off); | |
779 | struct disk_partitions *get_inner_parts(struct disk_partitions *parts); | 779 | struct disk_partitions *get_inner_parts(struct disk_partitions *parts); | |
780 | char* str_arg_subst(const char *, size_t, const char **); | 780 | char* str_arg_subst(const char *, size_t, const char **); | |
781 | void msg_display_subst(const char *, size_t, ...); | 781 | void msg_display_subst(const char *, size_t, ...); | |
782 | void msg_display_add_subst(const char *, size_t, ...); | 782 | void msg_display_add_subst(const char *, size_t, ...); | |
783 | int ask_yesno(const char *); | 783 | int ask_yesno(const char *); | |
784 | int ask_noyes(const char *); | 784 | int ask_noyes(const char *); | |
785 | void hit_enter_to_continue(const char *msg, const char *title); | 785 | void 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 | */ | |
792 | int ask_reedit(const struct disk_partitions *); | 792 | int ask_reedit(const struct disk_partitions *); | |
793 | int dir_exists_p(const char *); | 793 | int dir_exists_p(const char *); | |
794 | int file_exists_p(const char *); | 794 | int file_exists_p(const char *); | |
795 | int file_mode_match(const char *, unsigned int); | 795 | int file_mode_match(const char *, unsigned int); | |
796 | uint64_t get_ramsize(void); /* in MB! */ | 796 | uint64_t get_ramsize(void); /* in MB! */ | |
797 | void ask_sizemult(int); | 797 | void ask_sizemult(int); | |
798 | void run_makedev(void); | 798 | void run_makedev(void); | |
799 | int boot_media_still_needed(void); | 799 | int boot_media_still_needed(void); | |
800 | int get_via_floppy(void); | 800 | int get_via_floppy(void); | |
801 | int get_via_cdrom(void); | 801 | int get_via_cdrom(void); | |
802 | int get_via_localfs(void); | 802 | int get_via_localfs(void); | |
803 | int get_via_localdir(void); | 803 | int get_via_localdir(void); | |
804 | void show_cur_distsets(void); | 804 | void show_cur_distsets(void); | |
805 | void make_ramdisk_dir(const char *); | 805 | void make_ramdisk_dir(const char *); | |
806 | void set_kernel_set(unsigned int); | 806 | void set_kernel_set(unsigned int); | |
807 | void set_noextract_set(unsigned int); | 807 | void set_noextract_set(unsigned int); | |
808 | unsigned int get_kernel_set(void); | 808 | unsigned int get_kernel_set(void); | |
809 | unsigned int set_X11_selected(void); | 809 | unsigned int set_X11_selected(void); | |
810 | int get_and_unpack_sets(int, msg, msg, msg); | 810 | int get_and_unpack_sets(int, msg, msg, msg); | |
811 | int sanity_check(void); | 811 | int sanity_check(void); | |
812 | int set_timezone(void); | 812 | int set_timezone(void); | |
813 | void scripting_fprintf(FILE *, const char *, ...) __printflike(2, 3); | 813 | void scripting_fprintf(FILE *, const char *, ...) __printflike(2, 3); | |
814 | void scripting_vfprintf(FILE *, const char *, va_list) __printflike(2, 0); | 814 | void scripting_vfprintf(FILE *, const char *, va_list) __printflike(2, 0); | |
815 | void add_rc_conf(const char *, ...) __printflike(1, 2); | 815 | void add_rc_conf(const char *, ...) __printflike(1, 2); | |
816 | int del_rc_conf(const char *); | 816 | int del_rc_conf(const char *); | |
817 | void add_sysctl_conf(const char *, ...) __printflike(1, 2); | 817 | void add_sysctl_conf(const char *, ...) __printflike(1, 2); | |
818 | void enable_rc_conf(void); | 818 | void enable_rc_conf(void); | |
819 | void set_sizemult(daddr_t, uint bps); | 819 | void set_sizemult(daddr_t, uint bps); | |
820 | void set_default_sizemult(const char *disk, daddr_t unit, uint bps); | 820 | void set_default_sizemult(const char *disk, daddr_t unit, uint bps); | |
821 | int check_lfs_progs(void); | 821 | int check_lfs_progs(void); | |
822 | void init_set_status(int); | 822 | void init_set_status(int); | |
823 | void customise_sets(void); | 823 | void customise_sets(void); | |
824 | void umount_mnt2(void); | 824 | void umount_mnt2(void); | |
825 | int set_is_source(const char *); | 825 | int set_is_source(const char *); | |
826 | const char *set_dir_for_set(const char *); | 826 | const char *set_dir_for_set(const char *); | |
827 | const char *ext_dir_for_set(const char *); | 827 | const char *ext_dir_for_set(const char *); | |
828 | void replace(const char *, const char *, ...) __printflike(2, 3); | 828 | void replace(const char *, const char *, ...) __printflike(2, 3); | |
829 | void get_tz_default(void); | 829 | void get_tz_default(void); | |
830 | distinfo* get_set_distinfo(int); | 830 | distinfo* get_set_distinfo(int); | |
831 | int extract_file(distinfo *, int); | 831 | int extract_file(distinfo *, int); | |
832 | int extract_file_to(distinfo *dist, int update, const char *dest_dir, | 832 | int 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); | |
834 | void do_coloring (unsigned int, unsigned int); | 834 | void do_coloring (unsigned int, unsigned int); | |
835 | int set_menu_select(menudesc *, void *); | 835 | int set_menu_select(menudesc *, void *); | |
836 | const char *safectime(time_t *); | 836 | const char *safectime(time_t *); | |
837 | bool use_tgz_for_set(const char*); | 837 | bool use_tgz_for_set(const char*); | |
838 | const char *set_postfix(const char*); | 838 | const char *set_postfix(const char*); | |
839 | bool usage_set_from_parts(struct partition_usage_set*, | 839 | bool usage_set_from_parts(struct partition_usage_set*, | |
840 | struct disk_partitions*); | 840 | struct disk_partitions*); | |
841 | void free_usage_set(struct partition_usage_set*); | 841 | void free_usage_set(struct partition_usage_set*); | |
842 | bool install_desc_from_parts(struct install_partition_desc *, | 842 | bool install_desc_from_parts(struct install_partition_desc *, | |
843 | struct disk_partitions*); | 843 | struct disk_partitions*); | |
844 | void free_install_desc(struct install_partition_desc*); | 844 | void free_install_desc(struct install_partition_desc*); | |
845 | bool may_swap_if_not_sdmmc(const char*); | 845 | bool 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) | |
849 | void backtowin(void); | 849 | void backtowin(void); | |
850 | #endif | 850 | #endif | |
851 | bool is_root_part_mount(const char *); | 851 | bool is_root_part_mount(const char *); | |
852 | const char *concat_paths(const char *, const char *); | 852 | const char *concat_paths(const char *, const char *); | |
853 | const char *target_expand(const char *); | 853 | const char *target_expand(const char *); | |
854 | bool needs_expanding(const char *, size_t); | 854 | bool needs_expanding(const char *, size_t); | |
855 | void make_target_dir(const char *); | 855 | void make_target_dir(const char *); | |
856 | void append_to_target_file(const char *, const char *); | 856 | void append_to_target_file(const char *, const char *); | |
857 | void echo_to_target_file(const char *, const char *); | 857 | void echo_to_target_file(const char *, const char *); | |
858 | void trunc_target_file(const char *); | 858 | void trunc_target_file(const char *); | |
859 | const char *target_prefix(void); | 859 | const char *target_prefix(void); | |
860 | int target_chdir(const char *); | 860 | int target_chdir(const char *); | |
861 | void target_chdir_or_die(const char *); | 861 | void target_chdir_or_die(const char *); | |
862 | int target_already_root(void); | 862 | int target_already_root(void); | |
863 | FILE *target_fopen(const char *, const char *); | 863 | FILE *target_fopen(const char *, const char *); | |
864 | int target_collect_file(int, char **, const char *); | 864 | int target_collect_file(int, char **, const char *); | |
865 | int is_active_rootpart(const char *, int); | 865 | int is_active_rootpart(const char *, int); | |
866 | int cp_to_target(const char *, const char *); | 866 | int cp_to_target(const char *, const char *); | |
867 | void dup_file_into_target(const char *); | 867 | void dup_file_into_target(const char *); | |
868 | void mv_within_target_or_die(const char *, const char *); | 868 | void mv_within_target_or_die(const char *, const char *); | |
869 | int cp_within_target(const char *, const char *, int); | 869 | int cp_within_target(const char *, const char *, int); | |
870 | int target_mount(const char *, const char *, const char *); | 870 | int target_mount(const char *, const char *, const char *); | |
871 | int target_mount_do(const char *, const char *, const char *); | 871 | int target_mount_do(const char *, const char *, const char *); | |
872 | int target_test(unsigned int, const char *); | 872 | int target_test(unsigned int, const char *); | |
873 | int target_dir_exists_p(const char *); | 873 | int target_dir_exists_p(const char *); | |
874 | int target_file_exists_p(const char *); | 874 | int target_file_exists_p(const char *); | |
875 | int target_symlink_exists_p(const char *); | 875 | int target_symlink_exists_p(const char *); | |
876 | void unwind_mounts(void); | 876 | void unwind_mounts(void); | |
877 | int target_mounted(void); | 877 | int target_mounted(void); | |
878 | void umount_root(void); | 878 | void umount_root(void); | |
879 | 879 | |||
880 | /* from partman.c */ | 880 | /* from partman.c */ | |
881 | #ifndef NO_PARTMAN | 881 | #ifndef NO_PARTMAN | |
882 | int partman(void); | 882 | int partman(void); | |
883 | int pm_getrefdev(struct pm_devs *); | 883 | int pm_getrefdev(struct pm_devs *); | |
884 | void update_wedges(const char *); | 884 | void update_wedges(const char *); | |
885 | void pm_destroy_all(void); | 885 | void pm_destroy_all(void); | |
886 | #else | 886 | #else | |
887 | static inline int partman(void) { return -1; } | 887 | static inline int partman(void) { return -1; } | |
888 | static inline int pm_getrefdev(struct pm_devs *x __unused) { return -1; } | 888 | static 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 | |
891 | void pmdiskentry_enable(menudesc*, struct part_entry *); | 891 | void pmdiskentry_enable(menudesc*, struct part_entry *); | |
892 | int pm_partusage(struct pm_devs *, int, int); | 892 | int pm_partusage(struct pm_devs *, int, int); | |
893 | void pm_setfstype(struct pm_devs *, part_id, int, int); | 893 | void pm_setfstype(struct pm_devs *, part_id, int, int); | |
894 | void pm_set_lvmpv(struct pm_devs *, part_id, bool); | 894 | void pm_set_lvmpv(struct pm_devs *, part_id, bool); | |
895 | bool pm_is_lvmpv(struct pm_devs *, part_id, const struct disk_part_info*); | 895 | bool pm_is_lvmpv(struct pm_devs *, part_id, const struct disk_part_info*); | |
896 | int pm_editpart(int); | 896 | int pm_editpart(int); | |
897 | void pm_rename(struct pm_devs *); | 897 | void pm_rename(struct pm_devs *); | |
898 | void pm_shred(struct part_entry *, int); | 898 | void pm_shred(struct part_entry *, int); | |
899 | void pm_umount(struct pm_devs *, int); | 899 | void pm_umount(struct pm_devs *, int); | |
900 | int pm_unconfigure(struct pm_devs *); | 900 | int pm_unconfigure(struct pm_devs *); | |
901 | int pm_cgd_edit_new(struct pm_devs *pm, part_id id); | 901 | int pm_cgd_edit_new(struct pm_devs *pm, part_id id); | |
902 | int pm_cgd_edit_old(struct part_entry *); | 902 | int pm_cgd_edit_old(struct part_entry *); | |
903 | void pm_wedges_fill(struct pm_devs *); | 903 | void pm_wedges_fill(struct pm_devs *); | |
904 | void pm_edit_partitions(struct part_entry *); | 904 | void pm_edit_partitions(struct part_entry *); | |
905 | part_id pm_whole_disk(struct part_entry *, int); | 905 | part_id pm_whole_disk(struct part_entry *, int); | |
906 | struct pm_devs * pm_from_pe(struct part_entry *); | 906 | struct pm_devs * pm_from_pe(struct part_entry *); | |
907 | bool pm_force_parts(struct pm_devs *); | 907 | bool 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 | */ | |
916 | daddr_t parse_disk_pos( | 916 | daddr_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 */ | |
926 | extern int have_raid, have_vnd, have_cgd, have_lvm, have_gpt, have_dk; | 926 | extern int have_raid, have_vnd, have_cgd, have_lvm, have_gpt, have_dk; | |
927 | /* initialize above variables */ | 927 | /* initialize above variables */ | |
928 | void check_available_binaries(void); | 928 | void check_available_binaries(void); | |
929 | 929 | |||
930 | /* from bsddisklabel.c */ | 930 | /* from bsddisklabel.c */ | |
931 | bool make_bsd_partitions(struct install_partition_desc*); | 931 | bool make_bsd_partitions(struct install_partition_desc*); | |
932 | void set_ptn_titles(menudesc *, int, void *); | 932 | void set_ptn_titles(menudesc *, int, void *); | |
933 | int set_ptn_size(menudesc *, void *); | 933 | int set_ptn_size(menudesc *, void *); | |
934 | bool get_ptn_sizes(struct partition_usage_set*); | 934 | bool get_ptn_sizes(struct partition_usage_set*); | |
935 | bool check_partitions(struct install_partition_desc*); | 935 | bool check_partitions(struct install_partition_desc*); | |
936 | 936 | |||
937 | /* from aout2elf.c */ | 937 | /* from aout2elf.c */ | |
938 | int move_aout_libs(void); | 938 | int move_aout_libs(void); | |
939 | 939 | |||
940 | #ifdef WSKBD | 940 | #ifdef WSKBD | |
941 | void get_kb_encoding(void); | 941 | void get_kb_encoding(void); | |
942 | void save_kb_encoding(void); | 942 | void 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 */ | |
949 | void do_configmenu(struct install_partition_desc*); | 949 | void do_configmenu(struct install_partition_desc*); | |
950 | 950 | |||
951 | /* from checkrc.c */ | 951 | /* from checkrc.c */ | |
952 | int check_rcvar(const char *); | 952 | int check_rcvar(const char *); | |
953 | int check_rcdefault(const char *); | 953 | int check_rcdefault(const char *); | |
954 | WINDOW *mainwin; | 954 | extern WINDOW *mainwin; | |
955 | 955 | |||
956 | /* in menus.mi */ | 956 | /* in menus.mi */ | |
957 | void expand_all_option_texts(menudesc *menu, void *arg); | 957 | void expand_all_option_texts(menudesc *menu, void *arg); | |
958 | void resize_menu_height(menudesc *); | 958 | void resize_menu_height(menudesc *); | |
959 | 959 | |||
960 | #endif /* _DEFS_H_ */ | 960 | #endif /* _DEFS_H_ */ |
--- 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 | |||
55 | int debug; | |||
56 | char machine[SSTRSIZE]; | |||
57 | int ignorerror; | |||
58 | int ttysig_ignore; | |||
59 | pid_t ttysig_forward; | |||
60 | uint sizemult; | |||
61 | int partman_go; | |||
62 | FILE *logfp; | |||
63 | FILE *script; | |||
64 | daddr_t root_limit; | |||
65 | struct pm_head_t pm_head; | |||
66 | struct pm_devs *pm; | |||
67 | struct pm_devs *pm_new; | |||
68 | char xfer_dir[STRSIZE]; | |||
69 | int clean_xfer_dir; | |||
70 | char ext_dir_bin[STRSIZE]; | |||
71 | char ext_dir_src[STRSIZE]; | |||
72 | char ext_dir_pkgsrc[STRSIZE]; | |||
73 | char set_dir_bin[STRSIZE]; | |||
74 | char set_dir_src[STRSIZE]; | |||
75 | char pkg_dir[STRSIZE]; | |||
76 | char pkgsrc_dir[STRSIZE]; | |||
77 | const char *ushell; | |||
78 | struct ftpinfo ftp, pkg, pkgsrc; | |||
79 | int (*fetch_fn)(const char *); | |||
80 | char nfs_host[STRSIZE]; | |||
81 | char nfs_dir[STRSIZE]; | |||
82 | char cdrom_dev[SSTRSIZE]; | |||
83 | char fd_dev[SSTRSIZE]; | |||
84 | const char *fd_type; | |||
85 | char localfs_dev[SSTRSIZE]; | |||
86 | char localfs_fs[SSTRSIZE]; | |||
87 | char localfs_dir[STRSIZE]; | |||
88 | char targetroot_mnt[SSTRSIZE]; | |||
89 | int mnt2_mounted; | |||
90 | char dist_postfix[SSTRSIZE]; | |||
91 | char dist_tgz_postfix[SSTRSIZE]; | |||
92 | WINDOW *mainwin; | |||
93 | ||||
55 | static void select_language(void); | 94 | static 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); | |
58 | static void ttysighandler(int); | 97 | static void ttysighandler(int); | |
59 | static void cleanup(void); | 98 | static void cleanup(void); | |
60 | static void process_f_flag(char *); | 99 | static void process_f_flag(char *); | |
61 | 100 | |||
62 | static int exit_cleanly = 0; /* Did we finish nicely? */ | 101 | static int exit_cleanly = 0; /* Did we finish nicely? */ | |
63 | FILE *logfp; /* log file */ | 102 | FILE *logfp; /* log file */ | |
64 | FILE *script; /* script file */ | 103 | FILE *script; /* script file */ | |
65 | 104 | |||
66 | const char *multname; | 105 | const char *multname; | |
67 | const char *err_outofmem; | 106 | const char *err_outofmem; | |
68 | 107 | |||
69 | #ifdef DEBUG | 108 | #ifdef DEBUG | |
70 | extern int log_flip(void); | 109 | extern int log_flip(void); | |
71 | #endif | 110 | #endif | |
72 | 111 | |||
73 | /* Definion for colors */ | 112 | /* Definion for colors */ | |
74 | 113 | |||
75 | struct { | 114 | struct { | |
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 | |||
82 | struct f_arg { | 121 | struct 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 | |||
89 | static const struct f_arg fflagopts[] = { | 128 | static 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 | |||
131 | static void | 170 | static void | |
132 | init(void) | 171 | init(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 | |||
160 | static void | 199 | static void | |
161 | init_lang(void) | 200 | init_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 | |||
168 | int | 207 | int | |
169 | main(int argc, char **argv) | 208 | main(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 | |||
281 | static int | 320 | static int | |
282 | set_language(menudesc *m, void *arg) | 321 | set_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 | |||
290 | static void | 329 | static void | |
291 | select_language(void) | 330 | select_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 ... */ | |
401 | void | 440 | void | |
402 | toplevel(void) | 441 | toplevel(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 | |||
426 | static void | 465 | static void | |
427 | usage(void) | 466 | usage(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 */ | |
450 | static void | 489 | static void | |
451 | miscsighandler(int signo) | 490 | miscsighandler(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 | |||
461 | static void | 500 | static void | |
462 | ttysighandler(int signo) | 501 | ttysighandler(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 | |||
490 | static void | 529 | static void | |
491 | cleanup(void) | 530 | cleanup(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 | |||
527 | void | 566 | void | |
528 | process_f_flag(char *f_name) | 567 | process_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 | } |
--- 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 */ | |
98 | const struct { | 98 | const 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) */ | |
125 | struct mbr_part_type_info { | 125 | struct 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 | |||
131 | const struct disk_partitioning_scheme mbr_parts; | 131 | const struct disk_partitioning_scheme mbr_parts; | |
132 | struct mbr_disk_partitions { | 132 | struct 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 | |||
139 | const struct disk_partitioning_scheme mbr_parts; | 139 | const struct disk_partitioning_scheme mbr_parts; | |
140 | 140 | |||
141 | static size_t known_part_types = 0, last_added_part_type = 0; | 141 | static size_t known_part_types = 0, last_added_part_type = 0; | |
142 | static const size_t first_part_type = MBR_PTYPE_NETBSD; | 142 | static 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) */ | |
145 | struct mbr_part_type_info mbr_gen_type_desc[256]; | 145 | struct mbr_part_type_info mbr_gen_type_desc[256]; | |
146 | 146 | |||
147 | const struct disk_partitioning_scheme disklabel_parts; | 147 | extern const struct disk_partitioning_scheme disklabel_parts; | |
148 | 148 | |||
149 | static void convert_mbr_chs(int, int, int, uint8_t *, uint8_t *, | 149 | static void convert_mbr_chs(int, int, int, uint8_t *, uint8_t *, | |
150 | uint8_t *, uint32_t); | 150 | uint8_t *, uint32_t); | |
151 | 151 | |||
152 | static part_id mbr_add_part(struct disk_partitions *arg, | 152 | static 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 | |||
155 | static size_t mbr_get_free_spaces(const struct disk_partitions *arg, | 155 | static 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 | |||
159 | static size_t mbr_type_from_gen_desc(const struct part_type_desc *desc); | 159 | static 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 | |
200 | static void | 200 | static void | |
201 | dump_mbr(mbr_info_t *m, const char *label) | 201 | dump_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 | */ | |
242 | static ssize_t | 242 | static ssize_t | |
243 | blockread(int fd, size_t secsize, void *buf, size_t nbytes, off_t offset) | 243 | blockread(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 | */ | |
271 | static ssize_t | 271 | static ssize_t | |
272 | blockwrite(int fd, size_t secsize, const void *buf, size_t nbytes, | 272 | blockwrite(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 | |||
300 | static void | 300 | static void | |
301 | free_last_mounted(mbr_info_t *m) | 301 | free_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 | |||
309 | static void | 309 | static void | |
310 | free_mbr_info(mbr_info_t *m) | 310 | free_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 | */ | |
321 | bool | 321 | bool | |
322 | set_bios_geom_with_mbr_guess(struct disk_partitions *parts) | 322 | set_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 | |||
337 | static void | 337 | static void | |
338 | mbr_init_chs(struct mbr_disk_partitions *parts, int ncyl, int nhead, int nsec) | 338 | mbr_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 | */ | |
353 | void | 353 | void | |
354 | set_bios_geom(struct disk_partitions *parts, int *cyl, int *head, int *sec) | 354 | set_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 | |||
390 | static int | 390 | static int | |
391 | find_mbr_space(const struct mbr_info_t *mbrs, uint *start, uint *size, | 391 | find_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 | |
486 | static int | 486 | static int | |
487 | validate_and_set_names(mbr_info_t *mbri, const struct mbr_bootsel *src, | 487 | validate_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 | |||
524 | static int | 524 | static int | |
525 | valid_mbr(struct mbr_sector *mbrs) | 525 | valid_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 | |||
531 | static int | 531 | static int | |
532 | read_mbr(const char *disk, size_t secsize, mbr_info_t *mbri) | 532 | read_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 | |||
662 | static int | 662 | static int | |
663 | write_mbr(const char *disk, size_t secsize, mbr_info_t *mbri, int bsec, | 663 | write_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 | |||
788 | static void | 788 | static void | |
789 | convert_mbr_chs(int cyl, int head, int sec, | 789 | convert_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 | */ | |
819 | int | 819 | int | |
820 | guess_biosgeom_from_parts(struct disk_partitions *parts, | 820 | guess_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 | |||
852 | static int | 852 | static int | |
853 | mbr_comp_part_entry(const void *a, const void *b) | 853 | mbr_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 | |||
869 | static void | 869 | static void | |
870 | mbr_sort_main_mbr(struct mbr_sector *m) | 870 | mbr_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 | |||
876 | static void | 876 | static void | |
877 | mbr_init_default_alignments(struct mbr_disk_partitions *parts, uint track) | 877 | mbr_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 | |||
900 | static struct disk_partitions * | 900 | static struct disk_partitions * | |
901 | mbr_create_new(const char *disk, daddr_t start, daddr_t len, | 901 | mbr_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 | |||
939 | static void | 939 | static void | |
940 | mbr_calc_free_space(struct mbr_disk_partitions *parts) | 940 | mbr_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 | |||
974 | static struct disk_partitions * | 974 | static struct disk_partitions * | |
975 | mbr_read_from_disk(const char *disk, daddr_t start, daddr_t len, size_t bps, | 975 | mbr_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 | |||
1022 | static bool | 1022 | static bool | |
1023 | mbr_write_to_disk(struct disk_partitions *new_state) | 1023 | mbr_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 | |||
1049 | static bool | 1049 | static bool | |
1050 | mbr_change_disk_geom(struct disk_partitions *arg, int ncyl, int nhead, | 1050 | mbr_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 | |||
1094 | static size_t | 1094 | static size_t | |
1095 | mbr_type_from_gen_desc(const struct part_type_desc *desc) | 1095 | mbr_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 | |||
1104 | static enum part_type | 1104 | static enum part_type | |
1105 | mbr_map_part_type(unsigned int t) | 1105 | mbr_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 | |||
1127 | static void | 1127 | static void | |
1128 | map_mbr_part_types(void) | 1128 | map_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 | } |
--- 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 | |||
59 | typedef struct mbr_info_t mbr_info_t; | 59 | typedef struct mbr_info_t mbr_info_t; | |
60 | struct mbr_info_t { | 60 | struct 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 | |
79 | struct mbr_bootsel *mbs; | 79 | extern 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 */ | |
95 | void set_fdisk_geom(void); /* edit incore BIOS geometry */ | 95 | void set_fdisk_geom(void); /* edit incore BIOS geometry */ | |
96 | void disp_cur_geom(void); | 96 | void disp_cur_geom(void); | |
97 | int check_geom(void); /* primitive geometry sanity-check */ | 97 | int check_geom(void); /* primitive geometry sanity-check */ | |
98 | 98 | |||
99 | void disp_cur_part(struct mbr_partition *, int, int); | 99 | void disp_cur_part(struct mbr_partition *, int, int); | |
100 | int partsoverlap(struct mbr_partition *, int, int); | 100 | int partsoverlap(struct mbr_partition *, int, int); | |
101 | 101 | |||
102 | /* from mbr.c */ | 102 | /* from mbr.c */ | |
103 | 103 | |||
104 | int guess_biosgeom_from_parts(struct disk_partitions*, int *, int *, int *); | 104 | int guess_biosgeom_from_parts(struct disk_partitions*, int *, int *, int *); | |
105 | bool set_bios_geom_with_mbr_guess(struct disk_partitions*); | 105 | bool set_bios_geom_with_mbr_guess(struct disk_partitions*); | |
106 | void set_bios_geom(struct disk_partitions *, int *cyl, int *head, int *sec); | 106 | void set_bios_geom(struct disk_partitions *, int *cyl, int *head, int *sec); | |
107 | int otherpart(int); | 107 | int otherpart(int); | |
108 | int ourpart(int); | 108 | int ourpart(int); | |
109 | void edit_ptn_bounds(void); | 109 | void edit_ptn_bounds(void); | |
110 | #ifdef BOOTSEL | 110 | #ifdef BOOTSEL | |
111 | void disp_bootsel(void); | 111 | void disp_bootsel(void); | |
112 | void edit_bootsel_entry(int); | 112 | void edit_bootsel_entry(int); | |
113 | void edit_bootsel_timeout(void); | 113 | void edit_bootsel_timeout(void); | |
114 | void edit_bootsel_default_ptn(int); | 114 | void edit_bootsel_default_ptn(int); | |
115 | void edit_bootsel_default_disk(int); | 115 | void edit_bootsel_default_disk(int); | |
116 | void configure_bootsel(void); | 116 | void 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 | */ | |
130 | int md_check_mbr(struct disk_partitions*, mbr_info_t*, bool quiet); | 130 | int 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 | */ | |
136 | bool md_mbr_update_check(struct disk_partitions*, mbr_info_t*); | 136 | bool md_mbr_update_check(struct disk_partitions*, mbr_info_t*); | |
137 | 137 | |||
138 | #endif | 138 | #endif |