diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-12 19:30:44 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-12 19:30:44 +0000 |
commit | 98ae2160b62b99424e5793e97d5abd4e3c2e576b (patch) | |
tree | 58f4e56d32330ea4abe200f3b2b0e21392d944e1 /util-linux/fdisk_osf.c | |
parent | a6dbb08a48903cb8f31fad2cf2d1cffa92bd4808 (diff) | |
download | busybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.tar.gz busybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.tar.bz2 busybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.zip |
fdisk: separate sun/aix/etc code into #included files
Diffstat (limited to 'util-linux/fdisk_osf.c')
-rw-r--r-- | util-linux/fdisk_osf.c | 1046 |
1 files changed, 1046 insertions, 0 deletions
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c new file mode 100644 index 000000000..97fe79aca --- /dev/null +++ b/util-linux/fdisk_osf.c | |||
@@ -0,0 +1,1046 @@ | |||
1 | #ifdef CONFIG_FEATURE_OSF_LABEL | ||
2 | /* | ||
3 | * Copyright (c) 1987, 1988 Regents of the University of California. | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. All advertising materials mentioning features or use of this software | ||
15 | * must display the following acknowledgment: | ||
16 | * This product includes software developed by the University of | ||
17 | * California, Berkeley and its contributors. | ||
18 | * 4. Neither the name of the University nor the names of its contributors | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | |||
36 | #ifndef BSD_DISKMAGIC | ||
37 | #define BSD_DISKMAGIC ((uint32_t) 0x82564557) | ||
38 | #endif | ||
39 | |||
40 | #ifndef BSD_MAXPARTITIONS | ||
41 | #define BSD_MAXPARTITIONS 16 | ||
42 | #endif | ||
43 | |||
44 | #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" | ||
45 | |||
46 | #if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__m68k__) || defined (__mips__) || defined (__s390__) || defined (__sh__) || defined(__x86_64__) | ||
47 | #define BSD_LABELSECTOR 1 | ||
48 | #define BSD_LABELOFFSET 0 | ||
49 | #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__) | ||
50 | #define BSD_LABELSECTOR 0 | ||
51 | #define BSD_LABELOFFSET 64 | ||
52 | #elif defined (__s390__) || defined (__s390x__) | ||
53 | #define BSD_LABELSECTOR 1 | ||
54 | #define BSD_LABELOFFSET 0 | ||
55 | #else | ||
56 | #error unknown architecture | ||
57 | #endif | ||
58 | |||
59 | #define BSD_BBSIZE 8192 /* size of boot area, with label */ | ||
60 | #define BSD_SBSIZE 8192 /* max size of fs superblock */ | ||
61 | |||
62 | struct xbsd_disklabel { | ||
63 | uint32_t d_magic; /* the magic number */ | ||
64 | int16_t d_type; /* drive type */ | ||
65 | int16_t d_subtype; /* controller/d_type specific */ | ||
66 | char d_typename[16]; /* type name, e.g. "eagle" */ | ||
67 | char d_packname[16]; /* pack identifier */ | ||
68 | /* disk geometry: */ | ||
69 | uint32_t d_secsize; /* # of bytes per sector */ | ||
70 | uint32_t d_nsectors; /* # of data sectors per track */ | ||
71 | uint32_t d_ntracks; /* # of tracks per cylinder */ | ||
72 | uint32_t d_ncylinders; /* # of data cylinders per unit */ | ||
73 | uint32_t d_secpercyl; /* # of data sectors per cylinder */ | ||
74 | uint32_t d_secperunit; /* # of data sectors per unit */ | ||
75 | /* | ||
76 | * Spares (bad sector replacements) below | ||
77 | * are not counted in d_nsectors or d_secpercyl. | ||
78 | * Spare sectors are assumed to be physical sectors | ||
79 | * which occupy space at the end of each track and/or cylinder. | ||
80 | */ | ||
81 | uint16_t d_sparespertrack; /* # of spare sectors per track */ | ||
82 | uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ | ||
83 | /* | ||
84 | * Alternate cylinders include maintenance, replacement, | ||
85 | * configuration description areas, etc. | ||
86 | */ | ||
87 | uint32_t d_acylinders; /* # of alt. cylinders per unit */ | ||
88 | |||
89 | /* hardware characteristics: */ | ||
90 | /* | ||
91 | * d_interleave, d_trackskew and d_cylskew describe perturbations | ||
92 | * in the media format used to compensate for a slow controller. | ||
93 | * Interleave is physical sector interleave, set up by the formatter | ||
94 | * or controller when formatting. When interleaving is in use, | ||
95 | * logically adjacent sectors are not physically contiguous, | ||
96 | * but instead are separated by some number of sectors. | ||
97 | * It is specified as the ratio of physical sectors traversed | ||
98 | * per logical sector. Thus an interleave of 1:1 implies contiguous | ||
99 | * layout, while 2:1 implies that logical sector 0 is separated | ||
100 | * by one sector from logical sector 1. | ||
101 | * d_trackskew is the offset of sector 0 on track N | ||
102 | * relative to sector 0 on track N-1 on the same cylinder. | ||
103 | * Finally, d_cylskew is the offset of sector 0 on cylinder N | ||
104 | * relative to sector 0 on cylinder N-1. | ||
105 | */ | ||
106 | uint16_t d_rpm; /* rotational speed */ | ||
107 | uint16_t d_interleave; /* hardware sector interleave */ | ||
108 | uint16_t d_trackskew; /* sector 0 skew, per track */ | ||
109 | uint16_t d_cylskew; /* sector 0 skew, per cylinder */ | ||
110 | uint32_t d_headswitch; /* head switch time, usec */ | ||
111 | uint32_t d_trkseek; /* track-to-track seek, usec */ | ||
112 | uint32_t d_flags; /* generic flags */ | ||
113 | #define NDDATA 5 | ||
114 | uint32_t d_drivedata[NDDATA]; /* drive-type specific information */ | ||
115 | #define NSPARE 5 | ||
116 | uint32_t d_spare[NSPARE]; /* reserved for future use */ | ||
117 | uint32_t d_magic2; /* the magic number (again) */ | ||
118 | uint16_t d_checksum; /* xor of data incl. partitions */ | ||
119 | /* filesystem and partition information: */ | ||
120 | uint16_t d_npartitions; /* number of partitions in following */ | ||
121 | uint32_t d_bbsize; /* size of boot area at sn0, bytes */ | ||
122 | uint32_t d_sbsize; /* max size of fs superblock, bytes */ | ||
123 | struct xbsd_partition { /* the partition table */ | ||
124 | uint32_t p_size; /* number of sectors in partition */ | ||
125 | uint32_t p_offset; /* starting sector */ | ||
126 | uint32_t p_fsize; /* filesystem basic fragment size */ | ||
127 | uint8_t p_fstype; /* filesystem type, see below */ | ||
128 | uint8_t p_frag; /* filesystem fragments per block */ | ||
129 | uint16_t p_cpg; /* filesystem cylinders per group */ | ||
130 | } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ | ||
131 | }; | ||
132 | |||
133 | /* d_type values: */ | ||
134 | #define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ | ||
135 | #define BSD_DTYPE_MSCP 2 /* MSCP */ | ||
136 | #define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */ | ||
137 | #define BSD_DTYPE_SCSI 4 /* SCSI */ | ||
138 | #define BSD_DTYPE_ESDI 5 /* ESDI interface */ | ||
139 | #define BSD_DTYPE_ST506 6 /* ST506 etc. */ | ||
140 | #define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */ | ||
141 | #define BSD_DTYPE_HPFL 8 /* HP Fiber-link */ | ||
142 | #define BSD_DTYPE_FLOPPY 10 /* floppy */ | ||
143 | |||
144 | /* d_subtype values: */ | ||
145 | #define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */ | ||
146 | #define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */ | ||
147 | #define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */ | ||
148 | |||
149 | static const char * const xbsd_dktypenames[] = { | ||
150 | "unknown", | ||
151 | "SMD", | ||
152 | "MSCP", | ||
153 | "old DEC", | ||
154 | "SCSI", | ||
155 | "ESDI", | ||
156 | "ST506", | ||
157 | "HP-IB", | ||
158 | "HP-FL", | ||
159 | "type 9", | ||
160 | "floppy", | ||
161 | 0 | ||
162 | }; | ||
163 | #define BSD_DKMAXTYPES (sizeof(xbsd_dktypenames) / sizeof(xbsd_dktypenames[0]) - 1) | ||
164 | |||
165 | /* | ||
166 | * Filesystem type and version. | ||
167 | * Used to interpret other filesystem-specific | ||
168 | * per-partition information. | ||
169 | */ | ||
170 | #define BSD_FS_UNUSED 0 /* unused */ | ||
171 | #define BSD_FS_SWAP 1 /* swap */ | ||
172 | #define BSD_FS_V6 2 /* Sixth Edition */ | ||
173 | #define BSD_FS_V7 3 /* Seventh Edition */ | ||
174 | #define BSD_FS_SYSV 4 /* System V */ | ||
175 | #define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ | ||
176 | #define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */ | ||
177 | #define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */ | ||
178 | #define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */ | ||
179 | #define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */ | ||
180 | #define BSD_FS_HPFS 11 /* OS/2 high-performance file system */ | ||
181 | #define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */ | ||
182 | #define BSD_FS_ISOFS BSD_FS_ISO9660 | ||
183 | #define BSD_FS_BOOT 13 /* partition contains bootstrap */ | ||
184 | #define BSD_FS_ADOS 14 /* AmigaDOS fast file system */ | ||
185 | #define BSD_FS_HFS 15 /* Macintosh HFS */ | ||
186 | #define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */ | ||
187 | |||
188 | /* this is annoying, but it's also the way it is :-( */ | ||
189 | #ifdef __alpha__ | ||
190 | #define BSD_FS_EXT2 8 /* ext2 file system */ | ||
191 | #else | ||
192 | #define BSD_FS_MSDOS 8 /* MS-DOS file system */ | ||
193 | #endif | ||
194 | |||
195 | static const struct systypes xbsd_fstypes[] = { | ||
196 | { "\x00" "unused" }, /* BSD_FS_UNUSED */ | ||
197 | { "\x01" "swap" }, /* BSD_FS_SWAP */ | ||
198 | { "\x02" "Version 6" }, /* BSD_FS_V6 */ | ||
199 | { "\x03" "Version 7" }, /* BSD_FS_V7 */ | ||
200 | { "\x04" "System V" }, /* BSD_FS_SYSV */ | ||
201 | { "\x05" "4.1BSD" }, /* BSD_FS_V71K */ | ||
202 | { "\x06" "Eighth Edition" }, /* BSD_FS_V8 */ | ||
203 | { "\x07" "4.2BSD" }, /* BSD_FS_BSDFFS */ | ||
204 | #ifdef __alpha__ | ||
205 | { "\x08" "ext2" }, /* BSD_FS_EXT2 */ | ||
206 | #else | ||
207 | { "\x08" "MS-DOS" }, /* BSD_FS_MSDOS */ | ||
208 | #endif | ||
209 | { "\x09" "4.4LFS" }, /* BSD_FS_BSDLFS */ | ||
210 | { "\x0a" "unknown" }, /* BSD_FS_OTHER */ | ||
211 | { "\x0b" "HPFS" }, /* BSD_FS_HPFS */ | ||
212 | { "\x0c" "ISO-9660" }, /* BSD_FS_ISO9660 */ | ||
213 | { "\x0d" "boot" }, /* BSD_FS_BOOT */ | ||
214 | { "\x0e" "ADOS" }, /* BSD_FS_ADOS */ | ||
215 | { "\x0f" "HFS" }, /* BSD_FS_HFS */ | ||
216 | { "\x10" "AdvFS" }, /* BSD_FS_ADVFS */ | ||
217 | { NULL } | ||
218 | }; | ||
219 | #define BSD_FSMAXTYPES (SIZE(xbsd_fstypes)-1) | ||
220 | |||
221 | |||
222 | /* | ||
223 | * flags shared by various drives: | ||
224 | */ | ||
225 | #define BSD_D_REMOVABLE 0x01 /* removable media */ | ||
226 | #define BSD_D_ECC 0x02 /* supports ECC */ | ||
227 | #define BSD_D_BADSECT 0x04 /* supports bad sector forw. */ | ||
228 | #define BSD_D_RAMDISK 0x08 /* disk emulator */ | ||
229 | #define BSD_D_CHAIN 0x10 /* can do back-back transfers */ | ||
230 | #define BSD_D_DOSPART 0x20 /* within MSDOS partition */ | ||
231 | |||
232 | /* | ||
233 | Changes: | ||
234 | 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls | ||
235 | |||
236 | 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better | ||
237 | support for OSF/1 disklabels on Alpha. | ||
238 | Also fixed unaligned accesses in alpha_bootblock_checksum() | ||
239 | */ | ||
240 | |||
241 | static int possibly_osf_label; | ||
242 | |||
243 | #define FREEBSD_PARTITION 0xa5 | ||
244 | #define NETBSD_PARTITION 0xa9 | ||
245 | |||
246 | static void xbsd_delete_part(void); | ||
247 | static void xbsd_new_part(void); | ||
248 | static void xbsd_write_disklabel(void); | ||
249 | static int xbsd_create_disklabel(void); | ||
250 | static void xbsd_edit_disklabel(void); | ||
251 | static void xbsd_write_bootstrap(void); | ||
252 | static void xbsd_change_fstype(void); | ||
253 | static int xbsd_get_part_index(int max); | ||
254 | static int xbsd_check_new_partition(int *i); | ||
255 | static void xbsd_list_types(void); | ||
256 | static u_short xbsd_dkcksum(struct xbsd_disklabel *lp); | ||
257 | static int xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d); | ||
258 | static int xbsd_readlabel(struct partition *p, struct xbsd_disklabel *d); | ||
259 | static int xbsd_writelabel(struct partition *p, struct xbsd_disklabel *d); | ||
260 | |||
261 | #if defined (__alpha__) | ||
262 | static void alpha_bootblock_checksum(char *boot); | ||
263 | #endif | ||
264 | |||
265 | #if !defined (__alpha__) | ||
266 | static int xbsd_translate_fstype(int linux_type); | ||
267 | static void xbsd_link_part(void); | ||
268 | static struct partition *xbsd_part; | ||
269 | static int xbsd_part_index; | ||
270 | #endif | ||
271 | |||
272 | #if defined (__alpha__) | ||
273 | /* We access this through a uint64_t * when checksumming */ | ||
274 | static char disklabelbuffer[BSD_BBSIZE] ATTRIBUTE_ALIGNED(8); | ||
275 | #else | ||
276 | static char disklabelbuffer[BSD_BBSIZE]; | ||
277 | #endif | ||
278 | |||
279 | static struct xbsd_disklabel xbsd_dlabel; | ||
280 | |||
281 | #define bsd_cround(n) \ | ||
282 | (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n)) | ||
283 | |||
284 | /* | ||
285 | * Test whether the whole disk has BSD disk label magic. | ||
286 | * | ||
287 | * Note: often reformatting with DOS-type label leaves the BSD magic, | ||
288 | * so this does not mean that there is a BSD disk label. | ||
289 | */ | ||
290 | static int | ||
291 | check_osf_label(void) | ||
292 | { | ||
293 | if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0) | ||
294 | return 0; | ||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | static int | ||
299 | btrydev(const char * dev) | ||
300 | { | ||
301 | if (xbsd_readlabel (NULL, &xbsd_dlabel) == 0) | ||
302 | return -1; | ||
303 | printf(_("\nBSD label for device: %s\n"), dev); | ||
304 | xbsd_print_disklabel (0); | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static void | ||
309 | bmenu(void) | ||
310 | { | ||
311 | puts (_("Command action")); | ||
312 | puts (_("\td\tdelete a BSD partition")); | ||
313 | puts (_("\te\tedit drive data")); | ||
314 | puts (_("\ti\tinstall bootstrap")); | ||
315 | puts (_("\tl\tlist known filesystem types")); | ||
316 | puts (_("\tm\tprint this menu")); | ||
317 | puts (_("\tn\tadd a new BSD partition")); | ||
318 | puts (_("\tp\tprint BSD partition table")); | ||
319 | puts (_("\tq\tquit without saving changes")); | ||
320 | puts (_("\tr\treturn to main menu")); | ||
321 | puts (_("\ts\tshow complete disklabel")); | ||
322 | puts (_("\tt\tchange a partition's filesystem id")); | ||
323 | puts (_("\tu\tchange units (cylinders/sectors)")); | ||
324 | puts (_("\tw\twrite disklabel to disk")); | ||
325 | #if !defined (__alpha__) | ||
326 | puts (_("\tx\tlink BSD partition to non-BSD partition")); | ||
327 | #endif | ||
328 | } | ||
329 | |||
330 | #if !defined (__alpha__) | ||
331 | static int | ||
332 | hidden(int type) | ||
333 | { | ||
334 | return type ^ 0x10; | ||
335 | } | ||
336 | |||
337 | static int | ||
338 | is_bsd_partition_type(int type) | ||
339 | { | ||
340 | return (type == FREEBSD_PARTITION || | ||
341 | type == hidden(FREEBSD_PARTITION) || | ||
342 | type == NETBSD_PARTITION || | ||
343 | type == hidden(NETBSD_PARTITION)); | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | static void | ||
348 | bselect(void) | ||
349 | { | ||
350 | #if !defined (__alpha__) | ||
351 | int t, ss; | ||
352 | struct partition *p; | ||
353 | |||
354 | for (t = 0; t < 4; t++) { | ||
355 | p = get_part_table(t); | ||
356 | if (p && is_bsd_partition_type(p->sys_ind)) { | ||
357 | xbsd_part = p; | ||
358 | xbsd_part_index = t; | ||
359 | ss = get_start_sect(xbsd_part); | ||
360 | if (ss == 0) { | ||
361 | fprintf(stderr, _("Partition %s has invalid starting sector 0.\n"), | ||
362 | partname(disk_device, t+1, 0)); | ||
363 | return; | ||
364 | } | ||
365 | printf(_("Reading disklabel of %s at sector %d.\n"), | ||
366 | partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); | ||
367 | if (xbsd_readlabel(xbsd_part, &xbsd_dlabel) == 0) | ||
368 | if (xbsd_create_disklabel() == 0) | ||
369 | return; | ||
370 | break; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | if (t == 4) { | ||
375 | printf(_("There is no *BSD partition on %s.\n"), disk_device); | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | #elif defined (__alpha__) | ||
380 | |||
381 | if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0) | ||
382 | if (xbsd_create_disklabel() == 0) | ||
383 | exit (EXIT_SUCCESS); | ||
384 | |||
385 | #endif | ||
386 | |||
387 | while (1) { | ||
388 | putchar('\n'); | ||
389 | switch (tolower(read_nonempty(_("BSD disklabel command (m for help): ")))) { | ||
390 | case 'd': | ||
391 | xbsd_delete_part(); | ||
392 | break; | ||
393 | case 'e': | ||
394 | xbsd_edit_disklabel(); | ||
395 | break; | ||
396 | case 'i': | ||
397 | xbsd_write_bootstrap(); | ||
398 | break; | ||
399 | case 'l': | ||
400 | xbsd_list_types(); | ||
401 | break; | ||
402 | case 'n': | ||
403 | xbsd_new_part(); | ||
404 | break; | ||
405 | case 'p': | ||
406 | xbsd_print_disklabel(0); | ||
407 | break; | ||
408 | case 'q': | ||
409 | close(fd); | ||
410 | exit(EXIT_SUCCESS); | ||
411 | case 'r': | ||
412 | return; | ||
413 | case 's': | ||
414 | xbsd_print_disklabel(1); | ||
415 | break; | ||
416 | case 't': | ||
417 | xbsd_change_fstype(); | ||
418 | break; | ||
419 | case 'u': | ||
420 | change_units(); | ||
421 | break; | ||
422 | case 'w': | ||
423 | xbsd_write_disklabel(); | ||
424 | break; | ||
425 | #if !defined (__alpha__) | ||
426 | case 'x': | ||
427 | xbsd_link_part(); | ||
428 | break; | ||
429 | #endif | ||
430 | default: | ||
431 | bmenu(); | ||
432 | break; | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | |||
437 | static void | ||
438 | xbsd_delete_part(void) | ||
439 | { | ||
440 | int i; | ||
441 | |||
442 | i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); | ||
443 | xbsd_dlabel.d_partitions[i].p_size = 0; | ||
444 | xbsd_dlabel.d_partitions[i].p_offset = 0; | ||
445 | xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; | ||
446 | if (xbsd_dlabel.d_npartitions == i + 1) | ||
447 | while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0) | ||
448 | xbsd_dlabel.d_npartitions--; | ||
449 | } | ||
450 | |||
451 | static void | ||
452 | xbsd_new_part(void) | ||
453 | { | ||
454 | off_t begin, end; | ||
455 | char mesg[256]; | ||
456 | int i; | ||
457 | |||
458 | if (!xbsd_check_new_partition(&i)) | ||
459 | return; | ||
460 | |||
461 | #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__) | ||
462 | begin = get_start_sect(xbsd_part); | ||
463 | end = begin + get_nr_sects(xbsd_part) - 1; | ||
464 | #else | ||
465 | begin = 0; | ||
466 | end = xbsd_dlabel.d_secperunit - 1; | ||
467 | #endif | ||
468 | |||
469 | snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); | ||
470 | begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end), | ||
471 | 0, mesg); | ||
472 | |||
473 | if (display_in_cyl_units) | ||
474 | begin = (begin - 1) * xbsd_dlabel.d_secpercyl; | ||
475 | |||
476 | snprintf(mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"), | ||
477 | str_units(SINGULAR)); | ||
478 | end = read_int(bsd_cround (begin), bsd_cround (end), bsd_cround (end), | ||
479 | bsd_cround (begin), mesg); | ||
480 | |||
481 | if (display_in_cyl_units) | ||
482 | end = end * xbsd_dlabel.d_secpercyl - 1; | ||
483 | |||
484 | xbsd_dlabel.d_partitions[i].p_size = end - begin + 1; | ||
485 | xbsd_dlabel.d_partitions[i].p_offset = begin; | ||
486 | xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; | ||
487 | } | ||
488 | |||
489 | static void | ||
490 | xbsd_print_disklabel(int show_all) | ||
491 | { | ||
492 | struct xbsd_disklabel *lp = &xbsd_dlabel; | ||
493 | struct xbsd_partition *pp; | ||
494 | int i, j; | ||
495 | |||
496 | if (show_all) { | ||
497 | #if defined (__alpha__) | ||
498 | printf("# %s:\n", disk_device); | ||
499 | #else | ||
500 | printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0)); | ||
501 | #endif | ||
502 | if ((unsigned) lp->d_type < BSD_DKMAXTYPES) | ||
503 | printf(_("type: %s\n"), xbsd_dktypenames[lp->d_type]); | ||
504 | else | ||
505 | printf(_("type: %d\n"), lp->d_type); | ||
506 | printf(_("disk: %.*s\n"), (int) sizeof(lp->d_typename), lp->d_typename); | ||
507 | printf(_("label: %.*s\n"), (int) sizeof(lp->d_packname), lp->d_packname); | ||
508 | printf(_("flags:")); | ||
509 | if (lp->d_flags & BSD_D_REMOVABLE) | ||
510 | printf(_(" removable")); | ||
511 | if (lp->d_flags & BSD_D_ECC) | ||
512 | printf(_(" ecc")); | ||
513 | if (lp->d_flags & BSD_D_BADSECT) | ||
514 | printf(_(" badsect")); | ||
515 | printf("\n"); | ||
516 | /* On various machines the fields of *lp are short/int/long */ | ||
517 | /* In order to avoid problems, we cast them all to long. */ | ||
518 | printf(_("bytes/sector: %ld\n"), (long) lp->d_secsize); | ||
519 | printf(_("sectors/track: %ld\n"), (long) lp->d_nsectors); | ||
520 | printf(_("tracks/cylinder: %ld\n"), (long) lp->d_ntracks); | ||
521 | printf(_("sectors/cylinder: %ld\n"), (long) lp->d_secpercyl); | ||
522 | printf(_("cylinders: %ld\n"), (long) lp->d_ncylinders); | ||
523 | printf(_("rpm: %d\n"), lp->d_rpm); | ||
524 | printf(_("interleave: %d\n"), lp->d_interleave); | ||
525 | printf(_("trackskew: %d\n"), lp->d_trackskew); | ||
526 | printf(_("cylinderskew: %d\n"), lp->d_cylskew); | ||
527 | printf(_("headswitch: %ld\t\t# milliseconds\n"), | ||
528 | (long) lp->d_headswitch); | ||
529 | printf(_("track-to-track seek: %ld\t# milliseconds\n"), | ||
530 | (long) lp->d_trkseek); | ||
531 | printf(_("drivedata: ")); | ||
532 | for (i = NDDATA - 1; i >= 0; i--) | ||
533 | if (lp->d_drivedata[i]) | ||
534 | break; | ||
535 | if (i < 0) | ||
536 | i = 0; | ||
537 | for (j = 0; j <= i; j++) | ||
538 | printf("%ld ", (long) lp->d_drivedata[j]); | ||
539 | } | ||
540 | printf(_("\n%d partitions:\n"), lp->d_npartitions); | ||
541 | printf(_("# start end size fstype [fsize bsize cpg]\n")); | ||
542 | pp = lp->d_partitions; | ||
543 | for (i = 0; i < lp->d_npartitions; i++, pp++) { | ||
544 | if (pp->p_size) { | ||
545 | if (display_in_cyl_units && lp->d_secpercyl) { | ||
546 | printf(" %c: %8ld%c %8ld%c %8ld%c ", | ||
547 | 'a' + i, | ||
548 | (long) pp->p_offset / lp->d_secpercyl + 1, | ||
549 | (pp->p_offset % lp->d_secpercyl) ? '*' : ' ', | ||
550 | (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl, | ||
551 | ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ', | ||
552 | (long) pp->p_size / lp->d_secpercyl, | ||
553 | (pp->p_size % lp->d_secpercyl) ? '*' : ' ' | ||
554 | ); | ||
555 | } else { | ||
556 | printf(" %c: %8ld %8ld %8ld ", | ||
557 | 'a' + i, | ||
558 | (long) pp->p_offset, | ||
559 | (long) pp->p_offset + pp->p_size - 1, | ||
560 | (long) pp->p_size | ||
561 | ); | ||
562 | } | ||
563 | |||
564 | if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES) | ||
565 | printf("%8.8s", xbsd_fstypes[pp->p_fstype].name); | ||
566 | else | ||
567 | printf("%8x", pp->p_fstype); | ||
568 | |||
569 | switch (pp->p_fstype) { | ||
570 | case BSD_FS_UNUSED: | ||
571 | printf(" %5ld %5ld %5.5s ", | ||
572 | (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, ""); | ||
573 | break; | ||
574 | case BSD_FS_BSDFFS: | ||
575 | printf(" %5ld %5ld %5d ", | ||
576 | (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg); | ||
577 | break; | ||
578 | default: | ||
579 | printf("%22.22s", ""); | ||
580 | break; | ||
581 | } | ||
582 | printf("\n"); | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | |||
587 | static void | ||
588 | xbsd_write_disklabel(void) | ||
589 | { | ||
590 | #if defined (__alpha__) | ||
591 | printf(_("Writing disklabel to %s.\n"), disk_device); | ||
592 | xbsd_writelabel(NULL, &xbsd_dlabel); | ||
593 | #else | ||
594 | printf(_("Writing disklabel to %s.\n"), | ||
595 | partname(disk_device, xbsd_part_index + 1, 0)); | ||
596 | xbsd_writelabel(xbsd_part, &xbsd_dlabel); | ||
597 | #endif | ||
598 | reread_partition_table(0); /* no exit yet */ | ||
599 | } | ||
600 | |||
601 | static int | ||
602 | xbsd_create_disklabel(void) | ||
603 | { | ||
604 | char c; | ||
605 | |||
606 | #if defined (__alpha__) | ||
607 | fprintf(stderr, _("%s contains no disklabel.\n"), disk_device); | ||
608 | #else | ||
609 | fprintf(stderr, _("%s contains no disklabel.\n"), | ||
610 | partname(disk_device, xbsd_part_index + 1, 0)); | ||
611 | #endif | ||
612 | |||
613 | while (1) { | ||
614 | c = read_nonempty(_("Do you want to create a disklabel? (y/n) ")); | ||
615 | if (c == 'y' || c == 'Y') { | ||
616 | if (xbsd_initlabel( | ||
617 | #if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \ | ||
618 | defined (__s390__) || defined (__s390x__) | ||
619 | NULL, &xbsd_dlabel | ||
620 | #else | ||
621 | xbsd_part, &xbsd_dlabel/* not used, xbsd_part_index*/ | ||
622 | #endif | ||
623 | ) == 1) { | ||
624 | xbsd_print_disklabel (1); | ||
625 | return 1; | ||
626 | } else | ||
627 | return 0; | ||
628 | } else if (c == 'n') | ||
629 | return 0; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | static int | ||
634 | edit_int(int def, char *mesg) | ||
635 | { | ||
636 | do { | ||
637 | fputs(mesg, stdout); | ||
638 | printf(" (%d): ", def); | ||
639 | if (!read_line()) | ||
640 | return def; | ||
641 | } while (!isdigit(*line_ptr)); | ||
642 | return atoi(line_ptr); | ||
643 | } | ||
644 | |||
645 | static void | ||
646 | xbsd_edit_disklabel(void) | ||
647 | { | ||
648 | struct xbsd_disklabel *d; | ||
649 | |||
650 | d = &xbsd_dlabel; | ||
651 | |||
652 | #if defined (__alpha__) || defined (__ia64__) | ||
653 | d->d_secsize = (u_long) edit_int((u_long) d->d_secsize ,_("bytes/sector")); | ||
654 | d->d_nsectors = (u_long) edit_int((u_long) d->d_nsectors ,_("sectors/track")); | ||
655 | d->d_ntracks = (u_long) edit_int((u_long) d->d_ntracks ,_("tracks/cylinder")); | ||
656 | d->d_ncylinders = (u_long) edit_int((u_long) d->d_ncylinders ,_("cylinders")); | ||
657 | #endif | ||
658 | |||
659 | /* d->d_secpercyl can be != d->d_nsectors * d->d_ntracks */ | ||
660 | while (1) { | ||
661 | d->d_secpercyl = (u_long) edit_int((u_long) d->d_nsectors * d->d_ntracks, | ||
662 | _("sectors/cylinder")); | ||
663 | if (d->d_secpercyl <= d->d_nsectors * d->d_ntracks) | ||
664 | break; | ||
665 | |||
666 | printf(_("Must be <= sectors/track * tracks/cylinder (default).\n")); | ||
667 | } | ||
668 | d->d_rpm = (u_short) edit_int((u_short) d->d_rpm ,_("rpm")); | ||
669 | d->d_interleave = (u_short) edit_int((u_short) d->d_interleave,_("interleave")); | ||
670 | d->d_trackskew = (u_short) edit_int((u_short) d->d_trackskew ,_("trackskew")); | ||
671 | d->d_cylskew = (u_short) edit_int((u_short) d->d_cylskew ,_("cylinderskew")); | ||
672 | d->d_headswitch = (u_long) edit_int((u_long) d->d_headswitch ,_("headswitch")); | ||
673 | d->d_trkseek = (u_long) edit_int((u_long) d->d_trkseek ,_("track-to-track seek")); | ||
674 | |||
675 | d->d_secperunit = d->d_secpercyl * d->d_ncylinders; | ||
676 | } | ||
677 | |||
678 | static int | ||
679 | xbsd_get_bootstrap (char *path, void *ptr, int size) | ||
680 | { | ||
681 | int fdb; | ||
682 | |||
683 | if ((fdb = open (path, O_RDONLY)) < 0) { | ||
684 | perror(path); | ||
685 | return 0; | ||
686 | } | ||
687 | if (read(fdb, ptr, size) < 0) { | ||
688 | perror(path); | ||
689 | close(fdb); | ||
690 | return 0; | ||
691 | } | ||
692 | printf(" ... %s\n", path); | ||
693 | close(fdb); | ||
694 | return 1; | ||
695 | } | ||
696 | |||
697 | static void | ||
698 | sync_disks(void) | ||
699 | { | ||
700 | printf(_("\nSyncing disks.\n")); | ||
701 | sync(); | ||
702 | sleep(4); /* What? */ | ||
703 | } | ||
704 | |||
705 | static void | ||
706 | xbsd_write_bootstrap(void) | ||
707 | { | ||
708 | char *bootdir = BSD_LINUX_BOOTDIR; | ||
709 | char path[MAXPATHLEN]; | ||
710 | char *dkbasename; | ||
711 | struct xbsd_disklabel dl; | ||
712 | char *d, *p, *e; | ||
713 | int sector; | ||
714 | |||
715 | if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI) | ||
716 | dkbasename = "sd"; | ||
717 | else | ||
718 | dkbasename = "wd"; | ||
719 | |||
720 | printf(_("Bootstrap: %sboot -> boot%s (%s): "), | ||
721 | dkbasename, dkbasename, dkbasename); | ||
722 | if (read_line()) { | ||
723 | line_ptr[strlen(line_ptr)-1] = '\0'; | ||
724 | dkbasename = line_ptr; | ||
725 | } | ||
726 | snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); | ||
727 | if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize)) | ||
728 | return; | ||
729 | |||
730 | /* We need a backup of the disklabel (xbsd_dlabel might have changed). */ | ||
731 | d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE]; | ||
732 | memmove(&dl, d, sizeof(struct xbsd_disklabel)); | ||
733 | |||
734 | /* The disklabel will be overwritten by 0's from bootxx anyway */ | ||
735 | memset(d, 0, sizeof(struct xbsd_disklabel)); | ||
736 | |||
737 | snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename); | ||
738 | if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize], | ||
739 | (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize)) | ||
740 | return; | ||
741 | |||
742 | e = d + sizeof(struct xbsd_disklabel); | ||
743 | for (p = d; p < e; p++) | ||
744 | if (*p) { | ||
745 | fprintf(stderr, _("Bootstrap overlaps with disk label!\n")); | ||
746 | exit(EXIT_FAILURE); | ||
747 | } | ||
748 | |||
749 | memmove(d, &dl, sizeof(struct xbsd_disklabel)); | ||
750 | |||
751 | #if defined (__powerpc__) || defined (__hppa__) | ||
752 | sector = 0; | ||
753 | #elif defined (__alpha__) | ||
754 | sector = 0; | ||
755 | alpha_bootblock_checksum(disklabelbuffer); | ||
756 | #else | ||
757 | sector = get_start_sect(xbsd_part); | ||
758 | #endif | ||
759 | |||
760 | if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) | ||
761 | fdisk_fatal(unable_to_seek); | ||
762 | if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) | ||
763 | fdisk_fatal(unable_to_write); | ||
764 | |||
765 | #if defined (__alpha__) | ||
766 | printf(_("Bootstrap installed on %s.\n"), disk_device); | ||
767 | #else | ||
768 | printf(_("Bootstrap installed on %s.\n"), | ||
769 | partname (disk_device, xbsd_part_index+1, 0)); | ||
770 | #endif | ||
771 | |||
772 | sync_disks(); | ||
773 | } | ||
774 | |||
775 | static void | ||
776 | xbsd_change_fstype(void) | ||
777 | { | ||
778 | int i; | ||
779 | |||
780 | i = xbsd_get_part_index(xbsd_dlabel.d_npartitions); | ||
781 | xbsd_dlabel.d_partitions[i].p_fstype = read_hex(xbsd_fstypes); | ||
782 | } | ||
783 | |||
784 | static int | ||
785 | xbsd_get_part_index(int max) | ||
786 | { | ||
787 | char prompt[256]; | ||
788 | char l; | ||
789 | |||
790 | snprintf(prompt, sizeof(prompt), _("Partition (a-%c): "), 'a' + max - 1); | ||
791 | do | ||
792 | l = tolower(read_nonempty(prompt)); | ||
793 | while (l < 'a' || l > 'a' + max - 1); | ||
794 | return l - 'a'; | ||
795 | } | ||
796 | |||
797 | static int | ||
798 | xbsd_check_new_partition(int *i) | ||
799 | { | ||
800 | /* room for more? various BSD flavours have different maxima */ | ||
801 | if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) { | ||
802 | int t; | ||
803 | |||
804 | for (t = 0; t < BSD_MAXPARTITIONS; t++) | ||
805 | if (xbsd_dlabel.d_partitions[t].p_size == 0) | ||
806 | break; | ||
807 | |||
808 | if (t == BSD_MAXPARTITIONS) { | ||
809 | fprintf(stderr, _("The maximum number of partitions " | ||
810 | "has been created\n")); | ||
811 | return 0; | ||
812 | } | ||
813 | } | ||
814 | |||
815 | *i = xbsd_get_part_index (BSD_MAXPARTITIONS); | ||
816 | |||
817 | if (*i >= xbsd_dlabel.d_npartitions) | ||
818 | xbsd_dlabel.d_npartitions = (*i) + 1; | ||
819 | |||
820 | if (xbsd_dlabel.d_partitions[*i].p_size != 0) { | ||
821 | fprintf(stderr, _("This partition already exists.\n")); | ||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | return 1; | ||
826 | } | ||
827 | |||
828 | static void | ||
829 | xbsd_list_types(void) | ||
830 | { | ||
831 | list_types(xbsd_fstypes); | ||
832 | } | ||
833 | |||
834 | static u_short | ||
835 | xbsd_dkcksum(struct xbsd_disklabel *lp) | ||
836 | { | ||
837 | u_short *start, *end; | ||
838 | u_short sum = 0; | ||
839 | |||
840 | start = (u_short *) lp; | ||
841 | end = (u_short *) &lp->d_partitions[lp->d_npartitions]; | ||
842 | while (start < end) | ||
843 | sum ^= *start++; | ||
844 | return sum; | ||
845 | } | ||
846 | |||
847 | static int | ||
848 | xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d) | ||
849 | { | ||
850 | struct xbsd_partition *pp; | ||
851 | |||
852 | get_geometry(); | ||
853 | memset(d, 0, sizeof(struct xbsd_disklabel)); | ||
854 | |||
855 | d->d_magic = BSD_DISKMAGIC; | ||
856 | |||
857 | if (strncmp(disk_device, "/dev/sd", 7) == 0) | ||
858 | d->d_type = BSD_DTYPE_SCSI; | ||
859 | else | ||
860 | d->d_type = BSD_DTYPE_ST506; | ||
861 | |||
862 | #if !defined (__alpha__) | ||
863 | d->d_flags = BSD_D_DOSPART; | ||
864 | #else | ||
865 | d->d_flags = 0; | ||
866 | #endif | ||
867 | d->d_secsize = SECTOR_SIZE; /* bytes/sector */ | ||
868 | d->d_nsectors = sectors; /* sectors/track */ | ||
869 | d->d_ntracks = heads; /* tracks/cylinder (heads) */ | ||
870 | d->d_ncylinders = cylinders; | ||
871 | d->d_secpercyl = sectors * heads;/* sectors/cylinder */ | ||
872 | if (d->d_secpercyl == 0) | ||
873 | d->d_secpercyl = 1; /* avoid segfaults */ | ||
874 | d->d_secperunit = d->d_secpercyl * d->d_ncylinders; | ||
875 | |||
876 | d->d_rpm = 3600; | ||
877 | d->d_interleave = 1; | ||
878 | d->d_trackskew = 0; | ||
879 | d->d_cylskew = 0; | ||
880 | d->d_headswitch = 0; | ||
881 | d->d_trkseek = 0; | ||
882 | |||
883 | d->d_magic2 = BSD_DISKMAGIC; | ||
884 | d->d_bbsize = BSD_BBSIZE; | ||
885 | d->d_sbsize = BSD_SBSIZE; | ||
886 | |||
887 | #if !defined (__alpha__) | ||
888 | d->d_npartitions = 4; | ||
889 | pp = &d->d_partitions[2]; /* Partition C should be | ||
890 | the NetBSD partition */ | ||
891 | pp->p_offset = get_start_sect(p); | ||
892 | pp->p_size = get_nr_sects(p); | ||
893 | pp->p_fstype = BSD_FS_UNUSED; | ||
894 | pp = &d->d_partitions[3]; /* Partition D should be | ||
895 | the whole disk */ | ||
896 | pp->p_offset = 0; | ||
897 | pp->p_size = d->d_secperunit; | ||
898 | pp->p_fstype = BSD_FS_UNUSED; | ||
899 | #elif defined (__alpha__) | ||
900 | d->d_npartitions = 3; | ||
901 | pp = &d->d_partitions[2]; /* Partition C should be | ||
902 | the whole disk */ | ||
903 | pp->p_offset = 0; | ||
904 | pp->p_size = d->d_secperunit; | ||
905 | pp->p_fstype = BSD_FS_UNUSED; | ||
906 | #endif | ||
907 | |||
908 | return 1; | ||
909 | } | ||
910 | |||
911 | /* | ||
912 | * Read a xbsd_disklabel from sector 0 or from the starting sector of p. | ||
913 | * If it has the right magic, return 1. | ||
914 | */ | ||
915 | static int | ||
916 | xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d) | ||
917 | { | ||
918 | int t, sector; | ||
919 | |||
920 | /* p is used only to get the starting sector */ | ||
921 | #if !defined (__alpha__) | ||
922 | sector = (p ? get_start_sect(p) : 0); | ||
923 | #elif defined (__alpha__) | ||
924 | sector = 0; | ||
925 | #endif | ||
926 | |||
927 | if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) | ||
928 | fdisk_fatal(unable_to_seek); | ||
929 | if (BSD_BBSIZE != read(fd, disklabelbuffer, BSD_BBSIZE)) | ||
930 | fdisk_fatal(unable_to_read); | ||
931 | |||
932 | memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], | ||
933 | sizeof(struct xbsd_disklabel)); | ||
934 | |||
935 | if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) | ||
936 | return 0; | ||
937 | |||
938 | for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) { | ||
939 | d->d_partitions[t].p_size = 0; | ||
940 | d->d_partitions[t].p_offset = 0; | ||
941 | d->d_partitions[t].p_fstype = BSD_FS_UNUSED; | ||
942 | } | ||
943 | |||
944 | if (d->d_npartitions > BSD_MAXPARTITIONS) | ||
945 | fprintf(stderr, _("Warning: too many partitions " | ||
946 | "(%d, maximum is %d).\n"), | ||
947 | d->d_npartitions, BSD_MAXPARTITIONS); | ||
948 | return 1; | ||
949 | } | ||
950 | |||
951 | static int | ||
952 | xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d) | ||
953 | { | ||
954 | unsigned int sector; | ||
955 | |||
956 | #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__) | ||
957 | sector = get_start_sect(p) + BSD_LABELSECTOR; | ||
958 | #else | ||
959 | sector = BSD_LABELSECTOR; | ||
960 | #endif | ||
961 | |||
962 | d->d_checksum = 0; | ||
963 | d->d_checksum = xbsd_dkcksum (d); | ||
964 | |||
965 | /* This is necessary if we want to write the bootstrap later, | ||
966 | otherwise we'd write the old disklabel with the bootstrap. | ||
967 | */ | ||
968 | memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], | ||
969 | d, sizeof(struct xbsd_disklabel)); | ||
970 | |||
971 | #if defined (__alpha__) && BSD_LABELSECTOR == 0 | ||
972 | alpha_bootblock_checksum (disklabelbuffer); | ||
973 | if (lseek(fd, 0, SEEK_SET) == -1) | ||
974 | fdisk_fatal(unable_to_seek); | ||
975 | if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) | ||
976 | fdisk_fatal(unable_to_write); | ||
977 | #else | ||
978 | if (lseek(fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1) | ||
979 | fdisk_fatal(unable_to_seek); | ||
980 | if (sizeof(struct xbsd_disklabel) != write(fd, d, sizeof(struct xbsd_disklabel))) | ||
981 | fdisk_fatal(unable_to_write); | ||
982 | #endif | ||
983 | sync_disks(); | ||
984 | return 1; | ||
985 | } | ||
986 | |||
987 | |||
988 | #if !defined (__alpha__) | ||
989 | static int | ||
990 | xbsd_translate_fstype(int linux_type) | ||
991 | { | ||
992 | switch (linux_type) { | ||
993 | case 0x01: /* DOS 12-bit FAT */ | ||
994 | case 0x04: /* DOS 16-bit <32M */ | ||
995 | case 0x06: /* DOS 16-bit >=32M */ | ||
996 | case 0xe1: /* DOS access */ | ||
997 | case 0xe3: /* DOS R/O */ | ||
998 | case 0xf2: /* DOS secondary */ | ||
999 | return BSD_FS_MSDOS; | ||
1000 | case 0x07: /* OS/2 HPFS */ | ||
1001 | return BSD_FS_HPFS; | ||
1002 | default: | ||
1003 | return BSD_FS_OTHER; | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | static void | ||
1008 | xbsd_link_part(void) | ||
1009 | { | ||
1010 | int k, i; | ||
1011 | struct partition *p; | ||
1012 | |||
1013 | k = get_partition(1, partitions); | ||
1014 | |||
1015 | if (!xbsd_check_new_partition(&i)) | ||
1016 | return; | ||
1017 | |||
1018 | p = get_part_table(k); | ||
1019 | |||
1020 | xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p); | ||
1021 | xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p); | ||
1022 | xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind); | ||
1023 | } | ||
1024 | #endif | ||
1025 | |||
1026 | #if defined (__alpha__) | ||
1027 | |||
1028 | #if !defined(__GLIBC__) | ||
1029 | typedef unsigned long long uint64_t; | ||
1030 | #endif | ||
1031 | |||
1032 | static void | ||
1033 | alpha_bootblock_checksum(char *boot) | ||
1034 | { | ||
1035 | uint64_t *dp, sum; | ||
1036 | int i; | ||
1037 | |||
1038 | dp = (uint64_t *)boot; | ||
1039 | sum = 0; | ||
1040 | for (i = 0; i < 63; i++) | ||
1041 | sum += dp[i]; | ||
1042 | dp[63] = sum; | ||
1043 | } | ||
1044 | #endif /* __alpha__ */ | ||
1045 | |||
1046 | #endif /* OSF_LABEL */ | ||