fdisk.c revision 1.4 1 1.4 mycroft /*
2 1.1 cgd * Mach Operating System
3 1.1 cgd * Copyright (c) 1992 Carnegie Mellon University
4 1.1 cgd * All Rights Reserved.
5 1.4 mycroft *
6 1.1 cgd * Permission to use, copy, modify and distribute this software and its
7 1.1 cgd * documentation is hereby granted, provided that both the copyright
8 1.1 cgd * notice and this permission notice appear in all copies of the
9 1.1 cgd * software, derivative works or modified versions, and any portions
10 1.1 cgd * thereof, and that both notices appear in supporting documentation.
11 1.4 mycroft *
12 1.1 cgd * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 1.1 cgd * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 1.1 cgd * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 1.4 mycroft *
16 1.1 cgd * Carnegie Mellon requests users of this software to return to
17 1.4 mycroft *
18 1.1 cgd * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
19 1.1 cgd * School of Computer Science
20 1.1 cgd * Carnegie Mellon University
21 1.1 cgd * Pittsburgh PA 15213-3890
22 1.4 mycroft *
23 1.1 cgd * any improvements or extensions that they make and grant Carnegie Mellon
24 1.1 cgd * the rights to redistribute these changes.
25 1.1 cgd */
26 1.1 cgd
27 1.2 mycroft #ifndef lint
28 1.4 mycroft static char rcsid[] = "$Id: fdisk.c,v 1.4 1994/09/23 04:30:15 mycroft Exp $";
29 1.2 mycroft #endif /* not lint */
30 1.2 mycroft
31 1.1 cgd #include <sys/types.h>
32 1.1 cgd #include <sys/disklabel.h>
33 1.4 mycroft #include <sys/ioctl.h>
34 1.1 cgd #include <sys/stat.h>
35 1.4 mycroft
36 1.4 mycroft #include <err.h>
37 1.1 cgd #include <fcntl.h>
38 1.4 mycroft #include <stdio.h>
39 1.4 mycroft #include <stdlib.h>
40 1.1 cgd
41 1.1 cgd #define LBUF 100
42 1.1 cgd static char lbuf[LBUF];
43 1.1 cgd
44 1.1 cgd /*
45 1.1 cgd *
46 1.1 cgd * Ported to 386bsd by Julian Elischer Thu Oct 15 20:26:46 PDT 1992
47 1.1 cgd *
48 1.1 cgd * 14-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University
49 1.1 cgd * Copyright (c) 1989 Robert. V. Baron
50 1.1 cgd * Created.
51 1.1 cgd */
52 1.1 cgd
53 1.1 cgd #define Decimal(str, ans, tmp) if (decimal(str, &tmp, ans)) ans = tmp
54 1.1 cgd #define Hex(str, ans, tmp) if (hex(str, &tmp, ans)) ans = tmp
55 1.1 cgd #define String(str, ans, len) {char *z = ans; char **dflt = &z; if (string(str, dflt)) strncpy(ans, *dflt, len); }
56 1.1 cgd
57 1.1 cgd #define RoundCyl(x) ((((x) + cylsecs - 1) / cylsecs) * cylsecs)
58 1.1 cgd
59 1.1 cgd #define SECSIZE 512
60 1.1 cgd
61 1.1 cgd char *disk = "/dev/rwd0d";
62 1.1 cgd
63 1.1 cgd struct disklabel disklabel; /* disk parameters */
64 1.1 cgd
65 1.1 cgd int cyls, sectors, heads, cylsecs, disksecs;
66 1.1 cgd
67 1.4 mycroft struct mboot {
68 1.1 cgd unsigned char padding[2]; /* force the longs to be long alligned */
69 1.1 cgd unsigned char bootinst[DOSPARTOFF];
70 1.1 cgd struct dos_partition parts[4];
71 1.1 cgd unsigned short int signature;
72 1.1 cgd };
73 1.1 cgd struct mboot mboot;
74 1.1 cgd
75 1.1 cgd #define ACTIVE 0x80
76 1.1 cgd #define BOOT_MAGIC 0xAA55
77 1.1 cgd
78 1.1 cgd int dos_cyls;
79 1.1 cgd int dos_heads;
80 1.1 cgd int dos_sectors;
81 1.1 cgd int dos_cylsecs;
82 1.1 cgd
83 1.4 mycroft #define DOSSECT(s,c) (((s) & 0x3f) | (((c) >> 2) & 0xc0))
84 1.4 mycroft #define DOSCYL(c) ((c) & 0xff)
85 1.4 mycroft int partition = -1;
86 1.4 mycroft
87 1.4 mycroft int a_flag; /* set active partition */
88 1.4 mycroft int i_flag; /* replace partition data */
89 1.4 mycroft int u_flag; /* update partition data */
90 1.4 mycroft
91 1.4 mycroft unsigned char bootcode[] = {
92 1.4 mycroft 0x33, 0xc0, 0xfa, 0x8e, 0xd0, 0xbc, 0x00, 0x7c, 0x8e, 0xc0, 0x8e, 0xd8, 0xfb, 0x8b, 0xf4, 0xbf,
93 1.4 mycroft 0x00, 0x06, 0xb9, 0x00, 0x02, 0xfc, 0xf3, 0xa4, 0xea, 0x1d, 0x06, 0x00, 0x00, 0xb0, 0x04, 0xbe,
94 1.4 mycroft 0xbe, 0x07, 0x80, 0x3c, 0x80, 0x74, 0x0c, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x75, 0xf4, 0xbe, 0xbd,
95 1.4 mycroft 0x06, 0xeb, 0x43, 0x8b, 0xfe, 0x8b, 0x14, 0x8b, 0x4c, 0x02, 0x83, 0xc6, 0x10, 0xfe, 0xc8, 0x74,
96 1.4 mycroft 0x0a, 0x80, 0x3c, 0x80, 0x75, 0xf4, 0xbe, 0xbd, 0x06, 0xeb, 0x2b, 0xbd, 0x05, 0x00, 0xbb, 0x00,
97 1.4 mycroft 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13, 0x73, 0x0c, 0x33, 0xc0, 0xcd, 0x13, 0x4d, 0x75, 0xef, 0xbe,
98 1.4 mycroft 0x9e, 0x06, 0xeb, 0x12, 0x81, 0x3e, 0xfe, 0x7d, 0x55, 0xaa, 0x75, 0x07, 0x8b, 0xf7, 0xea, 0x00,
99 1.4 mycroft 0x7c, 0x00, 0x00, 0xbe, 0x85, 0x06, 0x2e, 0xac, 0x0a, 0xc0, 0x74, 0x06, 0xb4, 0x0e, 0xcd, 0x10,
100 1.1 cgd 0xeb, 0xf4, 0xfb, 0xeb, 0xfe,
101 1.1 cgd 'M', 'i', 's', 's', 'i', 'n', 'g', ' ',
102 1.1 cgd 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
103 1.4 mycroft 'E', 'r', 'r', 'o', 'r', ' ', 'l', 'o', 'a', 'd', 'i', 'n', 'g', ' ',
104 1.1 cgd 'o', 'p', 'e', 'r', 'a', 't', 'i', 'n', 'g', ' ', 's', 'y', 's', 't', 'e', 'm', 0,
105 1.1 cgd 'I', 'n', 'v', 'a', 'l', 'i', 'd', ' ',
106 1.1 cgd 'p', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n', ' ', 't', 'a', 'b', 'l', 'e', 0,
107 1.1 cgd 'A', 'u', 't', 'h', 'o', 'r', ' ', '-', ' ',
108 1.4 mycroft 'S', 'i', 'e', 'g', 'm', 'a', 'r', ' ', 'S', 'c', 'h', 'm', 'i', 'd', 't', 0,0,0,
109 1.1 cgd
110 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
122 1.4 mycroft 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
123 1.1 cgd };
124 1.1 cgd
125 1.4 mycroft struct part_type {
127 1.4 mycroft int type;
128 1.4 mycroft char *name;
129 1.4 mycroft } part_types[] = {
130 1.4 mycroft {0x00, "unused"},
131 1.4 mycroft {0x01, "Primary DOS with 12 bit FAT"},
132 1.4 mycroft {0x02, "XENIX / filesystem"},
133 1.4 mycroft {0x03, "XENIX /usr filesystem"},
134 1.4 mycroft {0x04, "Primary DOS with 16 bit FAT"},
135 1.4 mycroft {0x05, "Extended DOS"},
136 1.4 mycroft {0x06, "Primary 'big' DOS (> 32MB)"},
137 1.4 mycroft {0x07, "OS/2 HPFS, QNX or Advanced UNIX"},
138 1.4 mycroft {0x08, "AIX filesystem"},
139 1.4 mycroft {0x09, "AIX boot partition or Coherent"},
140 1.4 mycroft {0x0A, "OS/2 Boot Manager or OPUS"},
141 1.4 mycroft {0x10, "OPUS"},
142 1.4 mycroft {0x40, "VENIX 286"},
143 1.4 mycroft {0x50, "DM"},
144 1.4 mycroft {0x51, "DM"},
145 1.4 mycroft {0x52, "CP/M or Microport SysV/AT"},
146 1.4 mycroft {0x56, "GB"},
147 1.4 mycroft {0x61, "Speed"},
148 1.4 mycroft {0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"},
149 1.4 mycroft {0x64, "Novell Netware 2.xx"},
150 1.4 mycroft {0x65, "Novell Netware 3.xx"},
151 1.4 mycroft {0x75, "PCIX"},
152 1.4 mycroft {0x80, "Minix 1.1 ... 1.4a"},
153 1.4 mycroft {0x81, "Minix 1.4b ... 1.5.10"},
154 1.4 mycroft {0x82, "Linux"},
155 1.4 mycroft {0x93, "Amoeba filesystem"},
156 1.4 mycroft {0x94, "Amoeba bad block table"},
157 1.4 mycroft {0xA5, "NetBSD"},
158 1.4 mycroft {0xB7, "BSDI BSD/386 filesystem"},
159 1.4 mycroft {0xB8, "BSDI BSD/386 swap"},
160 1.4 mycroft {0xDB, "Concurrent CPM or C.DOS or CTOS"},
161 1.4 mycroft {0xE1, "Speed"},
162 1.4 mycroft {0xE3, "Speed"},
163 1.4 mycroft {0xE4, "Speed"},
164 1.4 mycroft {0xF1, "Speed"},
165 1.4 mycroft {0xF2, "DOS 3.3+ Secondary"},
166 1.4 mycroft {0xF4, "Speed"},
167 1.1 cgd {0xFF, "BBT (Bad Blocks Table)"},
168 1.1 cgd };
169 1.4 mycroft
170 1.4 mycroft void usage __P((void));
171 1.4 mycroft void print_s0 __P((int));
172 1.4 mycroft void print_part __P((int));
173 1.4 mycroft void init_sector0 __P((int));
174 1.4 mycroft void change_part __P((int));
175 1.4 mycroft void print_params __P((void));
176 1.4 mycroft void change_active __P((int));
177 1.4 mycroft void get_params_to_use __P((void));
178 1.4 mycroft void dos __P((int, unsigned char *, unsigned char *, unsigned char *));
179 1.4 mycroft int open_disk __P((int));
180 1.4 mycroft int read_disk __P((int, void *));
181 1.4 mycroft int write_disk __P((int, void *));
182 1.4 mycroft int get_params __P((void));
183 1.4 mycroft int read_s0 __P((void));
184 1.4 mycroft int write_s0 __P((void));
185 1.4 mycroft int yesno __P((char *));
186 1.4 mycroft int decimal __P((char *, int *, int));
187 1.4 mycroft int hex __P((char *, int *, int));
188 1.4 mycroft int string __P((char *, char **));
189 1.4 mycroft int type_match __P((const void *, const void *));
190 1.1 cgd char *get_type __P((int));
191 1.4 mycroft
192 1.1 cgd int
193 1.4 mycroft main(argc, argv)
194 1.4 mycroft int argc;
195 1.1 cgd char *argv[];
196 1.4 mycroft {
197 1.4 mycroft int ch;
198 1.1 cgd int part;
199 1.4 mycroft
200 1.4 mycroft a_flag = i_flag = u_flag = 0;
201 1.4 mycroft while ((ch = getopt(argc, argv, "0123aiu")) != -1)
202 1.4 mycroft switch (ch) {
203 1.4 mycroft case '0':
204 1.4 mycroft partition = 0;
205 1.4 mycroft break;
206 1.4 mycroft case '1':
207 1.4 mycroft partition = 1;
208 1.4 mycroft break;
209 1.4 mycroft case '2':
210 1.4 mycroft partition = 2;
211 1.4 mycroft break;
212 1.4 mycroft case '3':
213 1.4 mycroft partition = 3;
214 1.4 mycroft break;
215 1.4 mycroft case 'a':
216 1.4 mycroft a_flag = 1;
217 1.4 mycroft break;
218 1.4 mycroft case 'i':
219 1.4 mycroft i_flag = 1;
220 1.4 mycroft case 'u':
221 1.1 cgd u_flag = 1;
222 1.4 mycroft break;
223 1.4 mycroft default:
224 1.1 cgd usage();
225 1.4 mycroft }
226 1.4 mycroft argc -= optind;
227 1.1 cgd argv += optind;
228 1.1 cgd
229 1.1 cgd if (argc > 0)
230 1.4 mycroft disk = argv[0];
231 1.4 mycroft
232 1.1 cgd if (open_disk(a_flag || i_flag || u_flag) < 0)
233 1.1 cgd exit(1);
234 1.4 mycroft
235 1.4 mycroft printf("******* Working on device %s *******\n", disk);
236 1.1 cgd if (u_flag)
237 1.1 cgd get_params_to_use();
238 1.1 cgd else
239 1.1 cgd print_params();
240 1.1 cgd
241 1.1 cgd if (read_s0())
242 1.1 cgd init_sector0(1);
243 1.1 cgd
244 1.1 cgd printf("Warning: BIOS sector numbering starts with sector 1\n");
245 1.4 mycroft printf("Information from DOS bootblock is:\n");
246 1.4 mycroft if (partition == -1) {
247 1.4 mycroft for (part = 0; part < NDOSPART; part++)
248 1.4 mycroft change_part(part);
249 1.1 cgd } else
250 1.1 cgd change_part(partition);
251 1.1 cgd
252 1.1 cgd if (u_flag || a_flag)
253 1.1 cgd change_active(partition);
254 1.1 cgd
255 1.1 cgd if (u_flag || a_flag) {
256 1.1 cgd printf("\nWe haven't changed the partition table yet. ");
257 1.1 cgd printf("This is your last chance.\n");
258 1.4 mycroft print_s0(-1);
259 1.1 cgd if (yesno("Should we write new partition table?"))
260 1.1 cgd write_s0();
261 1.1 cgd }
262 1.1 cgd
263 1.4 mycroft exit(0);
264 1.1 cgd }
265 1.4 mycroft
266 1.4 mycroft void
267 1.4 mycroft usage()
268 1.4 mycroft {
269 1.4 mycroft
270 1.4 mycroft (void)fprintf(stderr, "usage: fdisk [-aiu] [-0|-1|-2|-3] [device]\n");
271 1.1 cgd exit(1);
272 1.1 cgd }
273 1.4 mycroft
274 1.1 cgd void
275 1.4 mycroft print_s0(which)
276 1.1 cgd int which;
277 1.4 mycroft {
278 1.1 cgd int part;
279 1.1 cgd
280 1.1 cgd print_params();
281 1.4 mycroft printf("Information from DOS bootblock is:\n");
282 1.4 mycroft if (which == -1) {
283 1.4 mycroft for (part = 0; part < NDOSPART; part++)
284 1.4 mycroft printf("%d: ", part), print_part(part);
285 1.1 cgd } else
286 1.1 cgd print_part(which);
287 1.1 cgd }
288 1.1 cgd
289 1.1 cgd static struct dos_partition mtpart = { 0 };
290 1.4 mycroft
291 1.4 mycroft void
292 1.4 mycroft print_part(part)
293 1.1 cgd int part;
294 1.4 mycroft {
295 1.1 cgd struct dos_partition *partp;
296 1.4 mycroft
297 1.4 mycroft partp = &mboot.parts[part];
298 1.1 cgd if (!bcmp(partp, &mtpart, sizeof(struct dos_partition))) {
299 1.1 cgd printf("<UNUSED>\n");
300 1.1 cgd return;
301 1.1 cgd }
302 1.4 mycroft printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ));
303 1.4 mycroft printf(" start %d, size %d (%d MB), flag %x\n",
304 1.4 mycroft partp->dp_start, partp->dp_size,
305 1.4 mycroft partp->dp_size * 512 / (1024 * 1024), partp->dp_flag);
306 1.4 mycroft printf("\tbeg: cyl %d/ sector %d/ head %d;\n",
307 1.4 mycroft DPCYL(partp->dp_scyl, partp->dp_ssect), DPSECT(partp->dp_ssect),
308 1.4 mycroft partp->dp_shd);
309 1.4 mycroft printf("\tend: cyl %d/ sector %d/ head %d\n",
310 1.4 mycroft DPCYL(partp->dp_ecyl, partp->dp_esect), DPSECT(partp->dp_esect),
311 1.1 cgd partp->dp_ehd);
312 1.1 cgd }
313 1.4 mycroft
314 1.1 cgd void
315 1.4 mycroft init_sector0(start)
316 1.1 cgd int start;
317 1.4 mycroft {
318 1.1 cgd struct dos_partition *partp;
319 1.4 mycroft
320 1.1 cgd memcpy(mboot.bootinst, bootcode, sizeof(bootcode));
321 1.1 cgd mboot.signature = BOOT_MAGIC;
322 1.4 mycroft
323 1.1 cgd partp = &mboot.parts[3];
324 1.1 cgd partp->dp_typ = DOSPTYP_386BSD;
325 1.1 cgd partp->dp_flag = ACTIVE;
326 1.4 mycroft partp->dp_start = start;
327 1.1 cgd partp->dp_size = disksecs - start;
328 1.4 mycroft
329 1.4 mycroft dos(partp->dp_start,
330 1.4 mycroft &partp->dp_scyl, &partp->dp_shd, &partp->dp_ssect);
331 1.4 mycroft dos(partp->dp_start + partp->dp_size - 1,
332 1.1 cgd &partp->dp_ecyl, &partp->dp_ehd, &partp->dp_esect);
333 1.1 cgd }
334 1.4 mycroft
335 1.4 mycroft void
336 1.4 mycroft change_part(part)
337 1.1 cgd int part;
338 1.4 mycroft {
339 1.4 mycroft struct dos_partition *partp;
340 1.1 cgd int tmp;
341 1.4 mycroft
342 1.1 cgd partp = &mboot.parts[part];
343 1.4 mycroft
344 1.4 mycroft printf("The data for partition %d is:\n", part);
345 1.4 mycroft print_part(part);
346 1.4 mycroft
347 1.4 mycroft if (!u_flag || !yesno("Do you want to change it?"))
348 1.1 cgd return;
349 1.1 cgd
350 1.4 mycroft if (i_flag) {
351 1.4 mycroft memset(partp, '\0', sizeof(*partp));
352 1.1 cgd if (part == 3) {
353 1.1 cgd init_sector0(1);
354 1.4 mycroft printf("\nThe static data for the DOS partition 3 has been reinitialized to:\n");
355 1.1 cgd print_part(part);
356 1.1 cgd }
357 1.1 cgd }
358 1.1 cgd
359 1.1 cgd do {
360 1.1 cgd Decimal("sysid", partp->dp_typ, tmp);
361 1.1 cgd Decimal("start", partp->dp_start, tmp);
362 1.1 cgd Decimal("size", partp->dp_size, tmp);
363 1.4 mycroft
364 1.4 mycroft if (yesno("Explicitly specifiy beg/end address ?")) {
365 1.4 mycroft int tsec, tcyl, thd;
366 1.4 mycroft
367 1.1 cgd tcyl = DPCYL(partp->dp_scyl, partp->dp_ssect);
368 1.1 cgd thd = partp->dp_shd;
369 1.1 cgd tsec = DPSECT(partp->dp_ssect);
370 1.1 cgd Decimal("beginning cylinder", tcyl, tmp);
371 1.1 cgd Decimal("beginning head", thd, tmp);
372 1.1 cgd Decimal("beginning sector", tsec, tmp);
373 1.1 cgd partp->dp_scyl = DOSCYL(tcyl);
374 1.4 mycroft partp->dp_shd = thd;
375 1.1 cgd partp->dp_ssect = DOSSECT(tsec, tcyl);
376 1.4 mycroft
377 1.1 cgd tcyl = DPCYL(partp->dp_ecyl, partp->dp_esect);
378 1.1 cgd thd = partp->dp_ehd;
379 1.1 cgd tsec = DPSECT(partp->dp_esect);
380 1.1 cgd Decimal("ending cylinder", tcyl, tmp);
381 1.1 cgd Decimal("ending head", thd, tmp);
382 1.1 cgd Decimal("ending sector", tsec, tmp);
383 1.1 cgd partp->dp_ecyl = DOSCYL(tcyl);
384 1.4 mycroft partp->dp_ehd = thd;
385 1.1 cgd partp->dp_esect = DOSSECT(tsec, tcyl);
386 1.1 cgd } else {
387 1.4 mycroft dos(partp->dp_start,
388 1.4 mycroft &partp->dp_scyl, &partp->dp_shd, &partp->dp_ssect);
389 1.4 mycroft dos(partp->dp_start + partp->dp_size - 1,
390 1.1 cgd &partp->dp_ecyl, &partp->dp_ehd, &partp->dp_esect);
391 1.4 mycroft }
392 1.4 mycroft
393 1.4 mycroft print_part(part);
394 1.1 cgd } while (!yesno("Are we happy with this entry?"));
395 1.1 cgd }
396 1.4 mycroft
397 1.1 cgd void
398 1.1 cgd print_params()
399 1.4 mycroft {
400 1.1 cgd
401 1.4 mycroft printf("parameters extracted from in-core disklabel are:\n");
402 1.4 mycroft printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n",
403 1.4 mycroft cyls, heads, sectors, cylsecs);
404 1.1 cgd if (dos_sectors > 63 || dos_cyls > 1023 || dos_heads > 255)
405 1.1 cgd printf(" Figures below won't work with BIOS for partitions not in cyl 1\n");
406 1.4 mycroft printf("parameters to be used for BIOS calculations are:\n");
407 1.4 mycroft printf("cylinders=%d heads=%d sectors/track=%d (%d blks/cyl)\n\n",
408 1.1 cgd dos_cyls, dos_heads, dos_sectors, dos_cylsecs);
409 1.1 cgd }
410 1.4 mycroft
411 1.1 cgd void
412 1.4 mycroft change_active(which)
413 1.1 cgd int which;
414 1.4 mycroft {
415 1.4 mycroft struct dos_partition *partp;
416 1.4 mycroft int part;
417 1.4 mycroft int active = 3, tmp;
418 1.4 mycroft
419 1.1 cgd partp = &mboot.parts[0];
420 1.1 cgd
421 1.1 cgd if (a_flag && which != -1)
422 1.4 mycroft active = which;
423 1.4 mycroft else {
424 1.4 mycroft for (part = 0; part < NDOSPART; part++)
425 1.4 mycroft if (partp[part].dp_flag & ACTIVE)
426 1.4 mycroft active = part;
427 1.4 mycroft }
428 1.4 mycroft if (yesno("Do you want to change the active partition?")) {
429 1.1 cgd do {
430 1.4 mycroft Decimal("active partition", active, tmp);
431 1.1 cgd } while (!yesno("Are you happy with this choice?"));
432 1.4 mycroft }
433 1.4 mycroft for (part = 0; part < NDOSPART; part++)
434 1.4 mycroft partp[part].dp_flag &= ~ACTIVE;
435 1.1 cgd partp[active].dp_flag |= ACTIVE;
436 1.1 cgd }
437 1.4 mycroft
438 1.1 cgd void
439 1.1 cgd get_params_to_use()
440 1.4 mycroft {
441 1.4 mycroft int tmp;
442 1.1 cgd
443 1.4 mycroft print_params();
444 1.4 mycroft if (yesno("Do you want to change our idea of what BIOS thinks?")) {
445 1.1 cgd do {
446 1.1 cgd Decimal("BIOS's idea of #cylinders", dos_cyls, tmp);
447 1.1 cgd Decimal("BIOS's idea of #heads", dos_heads, tmp);
448 1.1 cgd Decimal("BIOS's idea of #sectors", dos_sectors, tmp);
449 1.1 cgd dos_cylsecs = dos_heads * dos_sectors;
450 1.4 mycroft print_params();
451 1.1 cgd } while (!yesno("Are you happy with this choice?"));
452 1.1 cgd }
453 1.1 cgd }
454 1.1 cgd
455 1.1 cgd /***********************************************\
456 1.1 cgd * Change real numbers into strange dos numbers *
457 1.4 mycroft \***********************************************/
458 1.4 mycroft void
459 1.4 mycroft dos(sect, cylp, hdp, sectp)
460 1.4 mycroft int sect;
461 1.4 mycroft unsigned char *cylp, *hdp, *sectp;
462 1.4 mycroft {
463 1.4 mycroft int cyl, hd;
464 1.4 mycroft
465 1.4 mycroft cyl = sect / dos_cylsecs;
466 1.4 mycroft sect -= cyl * dos_cylsecs;
467 1.4 mycroft
468 1.4 mycroft hd = sect / dos_sectors;
469 1.4 mycroft sect -= hd * dos_sectors;
470 1.4 mycroft
471 1.4 mycroft *cylp = DOSCYL(cyl);
472 1.4 mycroft *hdp = hd;
473 1.1 cgd *sectp = DOSSECT(sect + 1, cyl);
474 1.1 cgd }
475 1.1 cgd
476 1.1 cgd int fd;
477 1.4 mycroft
478 1.1 cgd int
479 1.4 mycroft open_disk(u_flag)
480 1.1 cgd int u_flag;
481 1.4 mycroft {
482 1.1 cgd struct stat st;
483 1.4 mycroft
484 1.4 mycroft if ((fd = open(disk, u_flag ? O_RDWR : O_RDONLY)) == -1) {
485 1.4 mycroft warn("%s", disk);
486 1.4 mycroft return (-1);
487 1.4 mycroft }
488 1.4 mycroft if (fstat(fd, &st) == -1) {
489 1.4 mycroft close(fd);
490 1.4 mycroft warn("%s", disk);
491 1.1 cgd return (-1);
492 1.4 mycroft }
493 1.4 mycroft if (!S_ISCHR(st.st_mode)) {
494 1.4 mycroft close(fd);
495 1.4 mycroft warnx("%s is not a character device", disk);
496 1.1 cgd return (-1);
497 1.4 mycroft }
498 1.4 mycroft if (get_params() == -1) {
499 1.4 mycroft close(fd);
500 1.1 cgd return (-1);
501 1.4 mycroft }
502 1.1 cgd return (0);
503 1.1 cgd }
504 1.4 mycroft
505 1.1 cgd int
506 1.4 mycroft read_disk(sector, buf)
507 1.4 mycroft int sector;
508 1.1 cgd void *buf;
509 1.4 mycroft {
510 1.4 mycroft
511 1.4 mycroft if (lseek(fd, (off_t)(sector * 512), 0) == -1)
512 1.4 mycroft return (-1);
513 1.1 cgd return (read(fd, buf, 512));
514 1.1 cgd }
515 1.4 mycroft
516 1.1 cgd int
517 1.4 mycroft write_disk(sector, buf)
518 1.4 mycroft int sector;
519 1.1 cgd void *buf;
520 1.4 mycroft {
521 1.4 mycroft
522 1.4 mycroft if (lseek(fd, (off_t)(sector * 512), 0) == -1)
523 1.4 mycroft return (-1);
524 1.1 cgd return (write(fd, buf, 512));
525 1.1 cgd }
526 1.4 mycroft
527 1.4 mycroft int
528 1.1 cgd get_params()
529 1.1 cgd {
530 1.4 mycroft
531 1.4 mycroft if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
532 1.4 mycroft warn("DIOCGDINFO");
533 1.4 mycroft return (-1);
534 1.1 cgd }
535 1.4 mycroft
536 1.4 mycroft dos_cyls = cyls = disklabel.d_ncylinders;
537 1.4 mycroft dos_heads = heads = disklabel.d_ntracks;
538 1.4 mycroft dos_sectors = sectors = disklabel.d_nsectors;
539 1.4 mycroft dos_cylsecs = cylsecs = heads * sectors;
540 1.1 cgd disksecs = cyls * heads * sectors;
541 1.4 mycroft
542 1.1 cgd return (0);
543 1.1 cgd }
544 1.4 mycroft
545 1.1 cgd int
546 1.1 cgd read_s0()
547 1.4 mycroft {
548 1.4 mycroft
549 1.4 mycroft if (read_disk(0, mboot.bootinst) == -1) {
550 1.4 mycroft warn("can't read fdisk partition table");
551 1.1 cgd return (-1);
552 1.1 cgd }
553 1.4 mycroft if (mboot.signature != BOOT_MAGIC) {
554 1.4 mycroft warn("invalid fdisk partition table found");
555 1.4 mycroft /* So should we initialize things? */
556 1.1 cgd return (-1);
557 1.4 mycroft }
558 1.1 cgd return (0);
559 1.1 cgd }
560 1.4 mycroft
561 1.1 cgd int
562 1.1 cgd write_s0()
563 1.4 mycroft {
564 1.4 mycroft int flag;
565 1.1 cgd
566 1.1 cgd /*
567 1.1 cgd * write enable label sector before write (if necessary),
568 1.1 cgd * disable after writing.
569 1.1 cgd * needed if the disklabel protected area also protects
570 1.1 cgd * sector 0. (e.g. empty disk)
571 1.1 cgd */
572 1.1 cgd flag = 1;
573 1.4 mycroft if (ioctl(fd, DIOCWLABEL, &flag) < 0)
574 1.4 mycroft warn("DIOCWLABEL");
575 1.4 mycroft if (write_disk(0, mboot.bootinst) == -1) {
576 1.1 cgd warn("can't write fdisk partition table");
577 1.4 mycroft return -1;
578 1.1 cgd }
579 1.4 mycroft flag = 0;
580 1.4 mycroft if (ioctl(fd, DIOCWLABEL, &flag) < 0)
581 1.1 cgd warn("DIOCWLABEL");
582 1.1 cgd }
583 1.4 mycroft
584 1.4 mycroft int
585 1.4 mycroft yesno(str)
586 1.4 mycroft char *str;
587 1.4 mycroft {
588 1.1 cgd int ch, first;
589 1.1 cgd
590 1.1 cgd printf("%s [n] ", str);
591 1.4 mycroft
592 1.4 mycroft first = ch = getchar();
593 1.4 mycroft while (ch != '\n' && ch != EOF)
594 1.4 mycroft ch = getchar();
595 1.1 cgd return (first == 'y' || first == 'Y');
596 1.1 cgd }
597 1.4 mycroft
598 1.1 cgd int
599 1.4 mycroft decimal(str, num, deflt)
600 1.4 mycroft char *str;
601 1.1 cgd int *num, deflt;
602 1.4 mycroft {
603 1.4 mycroft int acc = 0, c;
604 1.1 cgd char *cp;
605 1.1 cgd
606 1.1 cgd while (1) {
607 1.1 cgd printf("Supply a decimal value for \"%s\" [%d] ", str, deflt);
608 1.1 cgd fgets(lbuf, LBUF, stdin);
609 1.1 cgd lbuf[strlen(lbuf)-1] = 0;
610 1.1 cgd
611 1.1 cgd if (!*lbuf)
612 1.1 cgd return 0;
613 1.1 cgd
614 1.1 cgd cp = lbuf;
615 1.1 cgd while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
616 1.1 cgd if (!c)
617 1.1 cgd return 0;
618 1.1 cgd while (c = *cp++) {
619 1.1 cgd if (c <= '9' && c >= '0')
620 1.1 cgd acc = acc * 10 + c - '0';
621 1.1 cgd else
622 1.1 cgd break;
623 1.1 cgd }
624 1.1 cgd if (c == ' ' || c == '\t')
625 1.1 cgd while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
626 1.1 cgd if (!c) {
627 1.1 cgd *num = acc;
628 1.1 cgd return 1;
629 1.1 cgd } else
630 1.1 cgd printf("%s is an invalid decimal number. Try again\n",
631 1.1 cgd lbuf);
632 1.1 cgd }
633 1.1 cgd
634 1.1 cgd }
635 1.4 mycroft
636 1.1 cgd int
637 1.4 mycroft hex(str, num, deflt)
638 1.4 mycroft char *str;
639 1.1 cgd int *num, deflt;
640 1.4 mycroft {
641 1.4 mycroft int acc = 0, c;
642 1.1 cgd char *cp;
643 1.1 cgd
644 1.1 cgd while (1) {
645 1.1 cgd printf("Supply a hex value for \"%s\" [%x] ", str, deflt);
646 1.1 cgd fgets(lbuf, LBUF, stdin);
647 1.1 cgd lbuf[strlen(lbuf)-1] = 0;
648 1.1 cgd
649 1.1 cgd if (!*lbuf)
650 1.1 cgd return 0;
651 1.1 cgd
652 1.1 cgd cp = lbuf;
653 1.1 cgd while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
654 1.1 cgd if (!c)
655 1.1 cgd return 0;
656 1.1 cgd while (c = *cp++) {
657 1.1 cgd if (c <= '9' && c >= '0')
658 1.1 cgd acc = (acc << 4) + c - '0';
659 1.1 cgd else if (c <= 'f' && c >= 'a')
660 1.1 cgd acc = (acc << 4) + c - 'a' + 10;
661 1.1 cgd else if (c <= 'F' && c >= 'A')
662 1.1 cgd acc = (acc << 4) + c - 'A' + 10;
663 1.1 cgd else
664 1.1 cgd break;
665 1.1 cgd }
666 1.1 cgd if (c == ' ' || c == '\t')
667 1.1 cgd while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
668 1.1 cgd if (!c) {
669 1.1 cgd *num = acc;
670 1.1 cgd return 1;
671 1.1 cgd } else
672 1.1 cgd printf("%s is an invalid hex number. Try again\n",
673 1.1 cgd lbuf);
674 1.1 cgd }
675 1.1 cgd
676 1.1 cgd }
677 1.4 mycroft
678 1.1 cgd int
679 1.4 mycroft string(str, ans)
680 1.4 mycroft char *str;
681 1.1 cgd char **ans;
682 1.4 mycroft {
683 1.4 mycroft int c;
684 1.1 cgd char *cp = lbuf;
685 1.1 cgd
686 1.1 cgd while (1) {
687 1.1 cgd printf("Supply a string value for \"%s\" [%s] ", str, *ans);
688 1.1 cgd fgets(lbuf, LBUF, stdin);
689 1.1 cgd lbuf[strlen(lbuf)-1] = 0;
690 1.1 cgd
691 1.1 cgd if (!*lbuf)
692 1.1 cgd return 0;
693 1.1 cgd
694 1.1 cgd while ((c = *cp) && (c == ' ' || c == '\t')) cp++;
695 1.1 cgd if (c == '"') {
696 1.1 cgd c = *++cp;
697 1.1 cgd *ans = cp;
698 1.1 cgd while ((c = *cp) && c != '"') cp++;
699 1.1 cgd } else {
700 1.1 cgd *ans = cp;
701 1.1 cgd while ((c = *cp) && c != ' ' && c != '\t') cp++;
702 1.1 cgd }
703 1.1 cgd
704 1.1 cgd if (c)
705 1.1 cgd *cp = 0;
706 1.1 cgd return 1;
707 1.1 cgd }
708 1.1 cgd }
709 1.4 mycroft
710 1.4 mycroft int
711 1.4 mycroft type_match(key, item)
712 1.4 mycroft const void *key, *item;
713 1.4 mycroft {
714 1.4 mycroft const int *typep = key;
715 1.4 mycroft const struct part_type *ptr = item;
716 1.4 mycroft
717 1.4 mycroft if (*typep < ptr->type)
718 1.4 mycroft return (-1);
719 1.4 mycroft if (*typep > ptr->type)
720 1.4 mycroft return (1);
721 1.4 mycroft return (0);
722 1.4 mycroft }
723 1.4 mycroft
724 1.4 mycroft char *
725 1.4 mycroft get_type(type)
726 1.4 mycroft int type;
727 1.4 mycroft {
728 1.4 mycroft struct part_type *ptr;
729 1.4 mycroft
730 1.4 mycroft ptr = bsearch(&type, part_types,
731 1.4 mycroft sizeof(part_types) / sizeof(struct part_type),
732 1.4 mycroft sizeof(struct part_type), type_match);
733 1.4 mycroft if (ptr == 0)
734 1.4 mycroft return ("unknown");
735 1.4 mycroft else
736 1.1 cgd return (ptr->name);
737 }
738