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