fdisk_osf.c 30 KB

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