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