Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / pdisk / dump.c
blob2844b9399fab779f967f3ea91cb90e5f5e9a0ebd
1 //
2 // dump.c - dumping partition maps
3 //
4 // Written by Eryk Vershen
5 //
7 /*
8 * Copyright 1996,1997,1998 by Apple Computer, Inc.
9 * All Rights Reserved
11 * Permission to use, copy, modify, and distribute this software and
12 * its documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appears in all copies and
14 * that both the copyright notice and this permission notice appear in
15 * supporting documentation.
17 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE.
21 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
24 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
25 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 // for *printf()
29 #include <stdio.h>
31 // for malloc() & free()
32 #ifndef __linux__
33 #include <stdlib.h>
34 //#include <unistd.h>
35 #else
36 #include <malloc.h>
37 #endif
39 // for strcmp()
40 #include <string.h>
41 // for O_RDONLY
42 #include <fcntl.h>
43 // for errno
44 #include <errno.h>
46 #include "dump.h"
47 #include "pathname.h"
48 #include "io.h"
49 #include "errors.h"
53 // Defines
55 #if DPISTRLEN != 32
56 #error Change in strlen in partition entries! Fix constants
57 #endif
59 #define get_align_long(x) (*(x))
63 // Types
65 typedef struct names {
66 const char *abbr;
67 const char *full;
68 } NAMES;
70 #ifdef __unix__
71 typedef unsigned long OSType;
72 #endif
74 typedef struct PatchDescriptor {
75 OSType patchSig;
76 unsigned short majorVers;
77 unsigned short minorVers;
78 unsigned long flags;
79 unsigned long patchOffset;
80 unsigned long patchSize;
81 unsigned long patchCRC;
82 unsigned long patchDescriptorLen;
83 unsigned char patchName[33];
84 unsigned char patchVendor[1];
85 } PatchDescriptor;
86 typedef PatchDescriptor * PatchDescriptorPtr;
88 typedef struct PatchList {
89 unsigned short numPatchBlocks; // number of disk blocks to hold the patch list
90 unsigned short numPatches; // number of patches in list
91 PatchDescriptor thePatch[1];
92 } PatchList;
93 typedef PatchList *PatchListPtr;
97 // Global Constants
99 NAMES plist[] = {
100 {"Drvr", "Apple_Driver"},
101 {"Drv4", "Apple_Driver43"},
102 {"Free", "Apple_Free"},
103 {"Patc", "Apple_Patches"},
104 {" HFS", "Apple_HFS"},
105 {" MFS", "Apple_MFS"},
106 {"PDOS", "Apple_PRODOS"},
107 {"junk", "Apple_Scratch"},
108 {"unix", "Apple_UNIX_SVR2"},
109 {" map", "Apple_partition_map"},
110 {0, 0},
113 const char * kStringEmpty = "";
114 const char * kStringNot = " not";
118 // Global Variables
120 int aflag = AFLAG_DEFAULT; /* abbreviate partition types */
121 int pflag = PFLAG_DEFAULT; /* show physical limits of partition */
122 int fflag = FFLAG_DEFAULT; /* show HFS volume names */
126 // Forward declarations
128 void adjust_value_and_compute_prefix(double *value, int *prefix);
129 void dump_block_zero(partition_map_header *map);
130 void dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits);
131 int get_max_base_or_length(partition_map_header *map);
132 int get_max_name_string_length(partition_map_header *map);
133 int get_max_type_string_length(partition_map_header *map);
137 // Routines
140 dump(char *name)
142 partition_map_header *map;
143 int junk;
145 map = open_partition_map(name, &junk, 0);
146 if (map == NULL) {
147 //error(-1, "No partition map in '%s'", name);
148 return 0;
151 dump_partition_map(map, 1);
153 close_partition_map(map);
155 return 1;
159 void
160 dump_block_zero(partition_map_header *map)
162 Block0 *p;
163 DDMap *m;
164 int i;
165 double value;
166 int prefix;
167 long t;
169 p = map->misc;
170 if (p->sbSig != BLOCK0_SIGNATURE) {
171 return;
174 value = ((double)p->sbBlkCount) * p->sbBlkSize;
175 adjust_value_and_compute_prefix(&value, &prefix);
176 printf("\nDevice block size=%u, Number of Blocks=%lu (%1.1f%c)\n",
177 p->sbBlkSize, p->sbBlkCount, value, prefix);
179 printf("DeviceType=0x%x, DeviceId=0x%x\n",
180 p->sbDevType, p->sbDevId);
181 if (p->sbDrvrCount > 0) {
182 printf("Drivers-\n");
183 m = (DDMap *) p->sbMap;
184 for (i = 0; i < p->sbDrvrCount; i++) {
185 printf("%u: %3u @ %lu, ", i+1,
186 m[i].ddSize, get_align_long(&m[i].ddBlock));
187 if (map->logical_block != p->sbBlkSize) {
188 t = (m[i].ddSize * p->sbBlkSize) / map->logical_block;
189 printf("(%lu@", t);
190 t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize)
191 / map->logical_block;
192 printf("%lu) ", t);
194 printf("type=0x%x\n", m[i].ddType);
197 printf("\n");
201 void
202 dump_partition_map(partition_map_header *map, int disk_order)
204 partition_map * entry;
205 int max_type_length;
206 int max_name_length;
207 int digits;
208 char *alternate;
210 if (map == NULL) {
211 bad_input("No partition map exists");
212 return;
214 alternate = get_linux_name(map->name);
215 if (alternate) {
216 printf("\nPartition map (with %d byte blocks) on '%s' (%s)\n",
217 map->logical_block, map->name, alternate);
218 free(alternate);
219 } else {
220 printf("\nPartition map (with %d byte blocks) on '%s'\n",
221 map->logical_block, map->name);
224 digits = number_of_digits(get_max_base_or_length(map));
225 if (digits < 6) {
226 digits = 6;
228 if (aflag) {
229 max_type_length = 4;
230 } else {
231 max_type_length = get_max_type_string_length(map);
232 if (max_type_length < 4) {
233 max_type_length = 4;
236 max_name_length = get_max_name_string_length(map);
237 if (max_name_length < 6) {
238 max_name_length = 6;
240 printf(" #: %*s %-*s %*s %-*s ( size )\n",
241 max_type_length, "type",
242 max_name_length, "name",
243 digits, "length", digits, "base");
245 if (disk_order) {
246 for (entry = map->disk_order; entry != NULL;
247 entry = entry->next_on_disk) {
249 dump_partition_entry(entry, max_type_length, max_name_length, digits);
251 } else {
252 for (entry = map->base_order; entry != NULL;
253 entry = entry->next_by_base) {
255 dump_partition_entry(entry, max_type_length, max_name_length, digits);
258 dump_block_zero(map);
262 void
263 dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits)
265 partition_map_header *map;
266 int j;
267 DPME *p;
268 const char *s;
269 u32 size;
270 double bytes;
271 int driver;
272 // int kind;
273 char *buf;
274 #if 1
275 BZB *bp;
276 #endif
278 map = entry->the_map;
279 p = entry->data;
280 driver = entry->contains_driver? '*': ' ';
281 if (aflag) {
282 s = "????";
283 for (j = 0; plist[j].abbr != 0; j++) {
284 if (strcmp(p->dpme_type, plist[j].full) == 0) {
285 s = plist[j].abbr;
286 break;
289 printf("%2ld: %.4s", entry->disk_address, s);
290 } else {
291 printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type);
294 buf = (char *) malloc(name_length+1);
295 if (entry->HFS_name == NULL || fflag == 0) {
296 strncpy(buf, p->dpme_name, name_length);
297 buf[name_length] = 0;
298 } else {
299 snprintf(buf, name_length + 1, "\"%s\"", entry->HFS_name);
301 printf("%c%-*.32s ", driver, name_length, buf);
302 free(buf);
304 switch (entry->HFS_kind) {
305 case kHFS_std: kind = 'h'; break;
306 case kHFS_embed: kind = 'e'; break;
307 case kHFS_plus: kind = '+'; break;
308 default:
309 case kHFS_not: kind = ' '; break;
311 printf("%c ", kind);
314 if (pflag) {
315 printf("%*lu ", digits, p->dpme_pblocks);
316 size = p->dpme_pblocks;
317 } else if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) {
318 printf("%*lu+", digits, p->dpme_lblocks);
319 size = p->dpme_lblocks;
320 } else if (p->dpme_lblock_start != 0) {
321 printf("%*lu ", digits, p->dpme_lblocks);
322 size = p->dpme_lblocks;
323 } else {
324 printf("%*lu ", digits, p->dpme_pblocks);
325 size = p->dpme_pblocks;
327 if (pflag || p->dpme_lblock_start == 0) {
328 printf("@ %-*lu", digits, p->dpme_pblock_start);
329 } else {
330 printf("@~%-*lu", digits, p->dpme_pblock_start + p->dpme_lblock_start);
333 bytes = ((double)size) * map->logical_block;
334 adjust_value_and_compute_prefix(&bytes, &j);
335 if (j != ' ' && j != 'K') {
336 printf(" (%#5.1f%c)", bytes, j);
339 #if 1
340 // Old A/UX fields that no one pays attention to anymore.
341 bp = (BZB *) (p->dpme_bzb);
342 j = -1;
343 if (bp->bzb_magic == BZBMAGIC) {
344 switch (bp->bzb_type) {
345 case FSTEFS:
346 s = "EFS";
347 break;
348 case FSTSFS:
349 s = "SFS";
350 j = 1;
351 break;
352 case FST:
353 default:
354 if (bzb_root_get(bp) != 0) {
355 if (bzb_usr_get(bp) != 0) {
356 s = "RUFS";
357 } else {
358 s = "RFS";
360 j = 0;
361 } else if (bzb_usr_get(bp) != 0) {
362 s = "UFS";
363 j = 2;
364 } else {
365 s = "FS";
367 break;
369 if (bzb_slice_get(bp) != 0) {
370 printf(" s%1ld %4s", bzb_slice_get(bp)-1, s);
371 } else if (j >= 0) {
372 printf(" S%1d %4s", j, s);
373 } else {
374 printf(" %4s", s);
376 if (bzb_crit_get(bp) != 0) {
377 printf(" K%1d", bp->bzb_cluster);
378 } else if (j < 0) {
379 printf(" ");
380 } else {
381 printf(" k%1d", bp->bzb_cluster);
383 if (bp->bzb_mount_point[0] != 0) {
384 printf(" %.64s", bp->bzb_mount_point);
387 #endif
388 printf("\n");
392 void
393 list_all_disks()
395 MEDIA_ITERATOR iter;
396 MEDIA m;
397 DPME * data;
398 char *name;
399 long mark;
401 data = (DPME *) malloc(PBLOCK_SIZE);
402 if (data == NULL) {
403 error(errno, "can't allocate memory for try buffer");
404 return;
407 for (iter = first_media_kind(&mark); iter != 0; iter = next_media_kind(&mark)) {
409 while ((name = step_media_iterator(iter)) != 0) {
411 if ((m = open_pathname_as_media(name, O_RDONLY)) == 0) {
412 #if defined(__linux__) || defined(__unix__)
413 error(errno, "can't open file '%s'", name);
414 #endif
415 } else {
416 close_media(m);
418 dump(name);
420 free(name);
423 delete_media_iterator(iter);
426 free(data);
430 void
431 show_data_structures(partition_map_header *map)
433 Block0 *zp;
434 DDMap *m;
435 int i;
436 int j;
437 partition_map * entry;
438 DPME *p;
439 BZB *bp;
440 const char *s;
442 if (map == NULL) {
443 printf("No partition map exists\n");
444 return;
446 printf("Header:\n");
447 printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n",
448 map->blocks_in_map, map->maximum_in_map,
449 map->media_size, map->logical_block);
450 printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot);
451 printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot);
452 printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot);
453 printf("\n");
455 if (map->misc == NULL) {
456 printf("No block zero\n");
457 } else {
458 zp = map->misc;
460 printf("Block0:\n");
461 printf("signature 0x%x", zp->sbSig);
462 if (zp->sbSig == BLOCK0_SIGNATURE) {
463 printf("\n");
464 } else {
465 printf(" should be 0x%x\n", BLOCK0_SIGNATURE);
467 printf("Block size=%u, Number of Blocks=%lu\n",
468 zp->sbBlkSize, zp->sbBlkCount);
469 printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%lx\n",
470 zp->sbDevType, zp->sbDevId, zp->sbData);
471 if (zp->sbDrvrCount == 0) {
472 printf("No drivers\n");
473 } else {
474 printf("%u driver%s-\n", zp->sbDrvrCount,
475 (zp->sbDrvrCount>1)?"s":kStringEmpty);
476 m = (DDMap *) zp->sbMap;
477 for (i = 0; i < zp->sbDrvrCount; i++) {
478 printf("%u: @ %lu for %u, type=0x%x\n", i+1,
479 get_align_long(&m[i].ddBlock),
480 m[i].ddSize, m[i].ddType);
484 printf("\n");
487 u32 dpme_boot_args[32] ;
488 u32 dpme_reserved_3[62] ;
490 printf(" #: type length base "
491 "flags (logical)\n");
492 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
493 p = entry->data;
494 printf("%2ld: %20.32s ",
495 entry->disk_address, p->dpme_type);
496 printf("%7lu @ %-7lu ", p->dpme_pblocks, p->dpme_pblock_start);
497 printf("%c%c%c%c%c%c%c%c%c%c%c%c ",
498 (dpme_valid_get(p))?'V':'.',
499 (dpme_allocated_get(p))?'A':'.',
500 (dpme_in_use_get(p))?'I':'.',
501 (dpme_bootable_get(p))?'B':'.',
502 (dpme_readable_get(p))?'R':'.',
503 (dpme_writable_get(p))?'W':'.',
504 (dpme_os_pic_code_get(p))?'P':'.',
505 (dpme_os_specific_2_get(p))?'2':'.',
506 (dpme_chainable_get(p))?'C':'.',
507 (dpme_diskdriver_get(p))?'D':'.',
508 (bitfield_get(p->dpme_flags, 30, 1))?'M':'.',
509 (bitfield_get(p->dpme_flags, 31, 1))?'X':'.');
510 if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) {
511 printf("(%lu @ %lu)", p->dpme_lblocks, p->dpme_lblock_start);
513 printf("\n");
515 printf("\n");
516 printf(" #: booter bytes load_address "
517 "goto_address checksum processor\n");
518 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
519 p = entry->data;
520 printf("%2ld: ", entry->disk_address);
521 printf("%7lu ", p->dpme_boot_block);
522 printf("%7lu ", p->dpme_boot_bytes);
523 printf("%8lx ", (u32)p->dpme_load_addr);
524 printf("%8lx ", (u32)p->dpme_load_addr_2);
525 printf("%8lx ", (u32)p->dpme_goto_addr);
526 printf("%8lx ", (u32)p->dpme_goto_addr_2);
527 printf("%8lx ", p->dpme_checksum);
528 printf("%.32s", p->dpme_process_id);
529 printf("\n");
531 printf("\n");
533 xx: cccc RU *dd s...
535 printf(" #: type RU *slice mount_point (A/UX only fields)\n");
536 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
537 p = entry->data;
538 printf("%2ld: ", entry->disk_address);
540 bp = (BZB *) (p->dpme_bzb);
541 j = -1;
542 if (bp->bzb_magic == BZBMAGIC) {
543 switch (bp->bzb_type) {
544 case FSTEFS:
545 s = "esch";
546 break;
547 case FSTSFS:
548 s = "swap";
549 j = 1;
550 break;
551 case FST:
552 default:
553 s = "fsys";
554 if (bzb_root_get(bp) != 0) {
555 j = 0;
556 } else if (bzb_usr_get(bp) != 0) {
557 j = 2;
559 break;
561 printf("%4s ", s);
562 printf("%c%c ",
563 (bzb_root_get(bp))?'R':' ',
564 (bzb_usr_get(bp))?'U':' ');
565 if (bzb_slice_get(bp) != 0) {
566 printf(" %2ld", bzb_slice_get(bp)-1);
567 } else if (j >= 0) {
568 printf(" *%2d", j);
569 } else {
570 printf(" ");
572 if (bp->bzb_mount_point[0] != 0) {
573 printf(" %.64s", bp->bzb_mount_point);
576 printf("\n");
581 void
582 full_dump_partition_entry(partition_map_header *map, int ix)
584 partition_map * cur;
585 DPME *p;
586 int i;
587 u32 t;
589 cur = find_entry_by_disk_address(ix, map);
590 if (cur == NULL) {
591 printf("No such partition\n");
592 return;
595 p = cur->data;
596 printf(" signature: 0x%x\n", p->dpme_signature);
597 printf(" reserved1: 0x%x\n", p->dpme_reserved_1);
598 printf(" number of map entries: %ld\n", p->dpme_map_entries);
599 printf(" physical start: %10lu length: %10lu\n", p->dpme_pblock_start, p->dpme_pblocks);
600 printf(" logical start: %10lu length: %10lu\n", p->dpme_lblock_start, p->dpme_lblocks);
602 printf(" flags: 0x%lx\n", (u32)p->dpme_flags);
603 printf(" ");
604 if (dpme_valid_get(p)) printf("valid ");
605 if (dpme_allocated_get(p)) printf("alloc ");
606 if (dpme_in_use_get(p)) printf("in-use ");
607 if (dpme_bootable_get(p)) printf("boot ");
608 if (dpme_readable_get(p)) printf("read ");
609 if (dpme_writable_get(p)) printf("write ");
610 if (dpme_os_pic_code_get(p)) printf("pic ");
611 t = p->dpme_flags >> 7;
612 for (i = 7; i <= 31; i++) {
613 if (t & 0x1) {
614 printf("%d ", i);
616 t = t >> 1;
618 printf("\n");
620 printf(" name: '%.32s'\n", p->dpme_name);
621 printf(" type: '%.32s'\n", p->dpme_type);
623 printf(" boot start block: %10lu\n", p->dpme_boot_block);
624 printf("boot length (in bytes): %10lu\n", p->dpme_boot_bytes);
625 printf(" load address: 0x%08lx 0x%08lx\n",
626 (u32)p->dpme_load_addr, (u32)p->dpme_load_addr_2);
627 printf(" start address: 0x%08lx 0x%08lx\n",
628 (u32)p->dpme_goto_addr, (u32)p->dpme_goto_addr_2);
629 printf(" checksum: 0x%08lx\n", p->dpme_checksum);
630 printf(" processor: '%.32s'\n", p->dpme_process_id);
631 printf("boot args field -");
632 dump_block((unsigned char *)p->dpme_boot_args, 32*4);
633 printf("dpme_reserved_3 -");
634 dump_block((unsigned char *)p->dpme_reserved_3, 62*4);
638 void
639 dump_block(unsigned char *addr, int len)
641 int i;
642 int j;
643 int limit1;
644 int limit;
645 #define LINE_LEN 16
646 #define UNIT_LEN 4
647 #define OTHER_LEN 8
649 for (i = 0; i < len; i = limit) {
650 limit1 = i + LINE_LEN;
651 if (limit1 > len) {
652 limit = len;
653 } else {
654 limit = limit1;
656 printf("\n%03x: ", i);
657 for (j = i; j < limit1; j++) {
658 if (j % UNIT_LEN == 0) {
659 printf(" ");
661 if (j < limit) {
662 printf("%02x", addr[j]);
663 } else {
664 printf(" ");
667 printf(" ");
668 for (j = i; j < limit; j++) {
669 if (j % OTHER_LEN == 0) {
670 printf(" ");
672 if (addr[j] < ' ') {
673 printf(".");
674 } else {
675 printf("%c", addr[j]);
679 printf("\n");
682 void
683 full_dump_block_zero(partition_map_header *map)
685 Block0 *zp;
686 DDMap *m;
687 int i;
689 if (map == NULL) {
690 printf("No partition map exists\n");
691 return;
694 if (map->misc == NULL) {
695 printf("No block zero\n");
696 return;
698 zp = map->misc;
700 printf(" signature: 0x%x\n", zp->sbSig);
701 printf(" size of a block: %d\n", zp->sbBlkSize);
702 printf(" number of blocks: %ld\n", zp->sbBlkCount);
703 printf(" device type: 0x%x\n", zp->sbDevType);
704 printf(" device id: 0x%x\n", zp->sbDevId);
705 printf(" data: 0x%lx\n", zp->sbData);
706 printf(" driver count: %d\n", zp->sbDrvrCount);
707 m = (DDMap *) zp->sbMap;
708 for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) {
709 if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) {
710 break;
712 printf(" driver %3u block: %ld\n", i+1, m[i].ddBlock);
713 printf(" size in blocks: %d\n", m[i].ddSize);
714 printf(" driver type: 0x%x\n", m[i].ddType);
716 printf("remainder of block -");
717 dump_block((unsigned char *)(void *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)(void *)&m[i].ddBlock))*2);
721 void
722 display_patches(partition_map *entry)
724 long long offset;
725 MEDIA m;
726 static unsigned char *patch_block;
727 PatchListPtr p;
728 PatchDescriptorPtr q;
729 unsigned char *next;
730 unsigned char *s;
731 int i;
733 offset = entry->data->dpme_pblock_start;
734 m = entry->the_map->m;
735 offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block;
736 if (patch_block == NULL) {
737 patch_block = (unsigned char *) malloc(PBLOCK_SIZE);
738 if (patch_block == NULL) {
739 error(errno, "can't allocate memory for patch block buffer");
740 return;
743 if (read_media(m, (long long)offset, PBLOCK_SIZE, (char *)patch_block) == 0) {
744 error(errno, "Can't read patch block");
745 return;
747 p = (PatchListPtr) patch_block;
748 if (p->numPatchBlocks != 1) {
749 i = p->numPatchBlocks;
750 free(patch_block);
751 patch_block = (unsigned char *) malloc(PBLOCK_SIZE*i);
752 if (patch_block == NULL) {
753 error(errno, "can't allocate memory for patch blocks buffer");
754 return;
756 s = patch_block + PBLOCK_SIZE*i;
757 while (i > 0) {
758 s -= PBLOCK_SIZE;
759 i -= 1;
760 if (read_media(m, offset+i, PBLOCK_SIZE, (char *)s) == 0) {
761 error(errno, "Can't read patch block %d", i);
762 return;
765 p = (PatchListPtr) patch_block;
767 printf("Patch list (%d entries)\n", p->numPatches);
768 q = p->thePatch;
769 for (i = 0; i < p->numPatches; i++) {
770 printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig);
771 printf(" version: %d.%d\n", q->majorVers, q->minorVers);
772 printf(" flags: 0x%lx\n", q->flags);
773 printf(" offset: %ld\n", q->patchOffset);
774 printf(" size: %ld\n", q->patchSize);
775 printf(" CRC: 0x%lx\n", q->patchCRC);
776 printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]);
777 printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]);
778 next = ((unsigned char *)q) + q->patchDescriptorLen;
779 s = &q->patchVendor[q->patchVendor[0]+1];
780 if (next > s) {
781 printf("remainder of entry -");
782 dump_block(s, next-s);
784 q = (PatchDescriptorPtr)next;
789 get_max_type_string_length(partition_map_header *map)
791 partition_map * entry;
792 int max;
793 int length;
795 if (map == NULL) {
796 return 0;
799 max = 0;
801 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
802 length = strnlen(entry->data->dpme_type, DPISTRLEN);
803 if (length > max) {
804 max = length;
808 return max;
812 get_max_name_string_length(partition_map_header *map)
814 partition_map * entry;
815 int max;
816 int length;
818 if (map == NULL) {
819 return 0;
822 max = 0;
824 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
825 length = strnlen(entry->data->dpme_name, DPISTRLEN);
826 if (length > max) {
827 max = length;
830 if (fflag) {
831 if (entry->HFS_name == NULL) {
832 length = 0;
833 } else {
834 length = strlen(entry->HFS_name) + 2;
836 if (length > max) {
837 max = length;
842 return max;
846 get_max_base_or_length(partition_map_header *map)
848 partition_map * entry;
849 unsigned int max;
851 if (map == NULL) {
852 return 0;
855 max = 0;
857 for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
858 if (entry->data->dpme_pblock_start > max) {
859 max = entry->data->dpme_pblock_start;
861 if (entry->data->dpme_pblocks > max) {
862 max = entry->data->dpme_pblocks;
864 if (entry->data->dpme_lblock_start > max) {
865 max = entry->data->dpme_lblock_start;
867 if (entry->data->dpme_lblocks > max) {
868 max = entry->data->dpme_lblocks;
872 return max;
875 void
876 adjust_value_and_compute_prefix(double *value, int *prefix)
878 double bytes;
879 int multiplier;
881 bytes = *value;
882 if (bytes < 1024.0) {
883 multiplier = ' ';
884 } else {
885 bytes = bytes / 1024.0;
886 if (bytes < 1024.0) {
887 multiplier = 'K';
888 } else {
889 bytes = bytes / 1024.0;
890 if (bytes < 1024.0) {
891 multiplier = 'M';
892 } else {
893 bytes = bytes / 1024.0;
894 if (bytes < 1024.0) {
895 multiplier = 'G';
896 } else {
897 bytes = bytes / 1024.0;
898 multiplier = 'T';
903 *value = bytes;
904 *prefix = multiplier;