1*dce63815Sdrahn // 2*dce63815Sdrahn // dump.c - dumping partition maps 3*dce63815Sdrahn // 4*dce63815Sdrahn // Written by Eryk Vershen (eryk@apple.com) 5*dce63815Sdrahn // 6*dce63815Sdrahn 7*dce63815Sdrahn /* 8*dce63815Sdrahn * Copyright 1996,1997,1998 by Apple Computer, Inc. 9*dce63815Sdrahn * All Rights Reserved 10*dce63815Sdrahn * 11*dce63815Sdrahn * Permission to use, copy, modify, and distribute this software and 12*dce63815Sdrahn * its documentation for any purpose and without fee is hereby granted, 13*dce63815Sdrahn * provided that the above copyright notice appears in all copies and 14*dce63815Sdrahn * that both the copyright notice and this permission notice appear in 15*dce63815Sdrahn * supporting documentation. 16*dce63815Sdrahn * 17*dce63815Sdrahn * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 18*dce63815Sdrahn * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19*dce63815Sdrahn * FOR A PARTICULAR PURPOSE. 20*dce63815Sdrahn * 21*dce63815Sdrahn * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 22*dce63815Sdrahn * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 23*dce63815Sdrahn * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 24*dce63815Sdrahn * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 25*dce63815Sdrahn * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 26*dce63815Sdrahn */ 27*dce63815Sdrahn 28*dce63815Sdrahn // for *printf() 29*dce63815Sdrahn #include <stdio.h> 30*dce63815Sdrahn 31*dce63815Sdrahn // for malloc() & free() 32*dce63815Sdrahn #ifndef __linux__ 33*dce63815Sdrahn #include <stdlib.h> 34*dce63815Sdrahn //#include <unistd.h> 35*dce63815Sdrahn #else 36*dce63815Sdrahn #include <malloc.h> 37*dce63815Sdrahn #endif 38*dce63815Sdrahn 39*dce63815Sdrahn // for strcmp() 40*dce63815Sdrahn #include <string.h> 41*dce63815Sdrahn // for O_RDONLY 42*dce63815Sdrahn #include <fcntl.h> 43*dce63815Sdrahn // for errno 44*dce63815Sdrahn #include <errno.h> 45*dce63815Sdrahn 46*dce63815Sdrahn #include "dump.h" 47*dce63815Sdrahn #include "pathname.h" 48*dce63815Sdrahn #include "io.h" 49*dce63815Sdrahn #include "errors.h" 50*dce63815Sdrahn 51*dce63815Sdrahn 52*dce63815Sdrahn // 53*dce63815Sdrahn // Defines 54*dce63815Sdrahn // 55*dce63815Sdrahn #if DPISTRLEN != 32 56*dce63815Sdrahn #error Change in strlen in partition entries! Fix constants 57*dce63815Sdrahn #endif 58*dce63815Sdrahn 59*dce63815Sdrahn #define get_align_long(x) (*(x)) 60*dce63815Sdrahn 61*dce63815Sdrahn 62*dce63815Sdrahn // 63*dce63815Sdrahn // Types 64*dce63815Sdrahn // 65*dce63815Sdrahn typedef struct names { 66*dce63815Sdrahn char *abbr; 67*dce63815Sdrahn char *full; 68*dce63815Sdrahn } NAMES; 69*dce63815Sdrahn 70*dce63815Sdrahn 71*dce63815Sdrahn // 72*dce63815Sdrahn // Global Constants 73*dce63815Sdrahn // 74*dce63815Sdrahn NAMES plist[] = { 75*dce63815Sdrahn {"Drvr", "Apple_Driver"}, 76*dce63815Sdrahn {"Free", "Apple_Free"}, 77*dce63815Sdrahn {" HFS", "Apple_HFS"}, 78*dce63815Sdrahn {" MFS", "Apple_MFS"}, 79*dce63815Sdrahn {"PDOS", "Apple_PRODOS"}, 80*dce63815Sdrahn {"junk", "Apple_Scratch"}, 81*dce63815Sdrahn {"unix", "Apple_UNIX_SVR2"}, 82*dce63815Sdrahn {" map", "Apple_partition_map"}, 83*dce63815Sdrahn {0, 0}, 84*dce63815Sdrahn }; 85*dce63815Sdrahn 86*dce63815Sdrahn const char * kStringEmpty = ""; 87*dce63815Sdrahn const char * kStringNot = " not"; 88*dce63815Sdrahn 89*dce63815Sdrahn 90*dce63815Sdrahn // 91*dce63815Sdrahn // Global Variables 92*dce63815Sdrahn // 93*dce63815Sdrahn int aflag = AFLAG_DEFAULT; /* abbreviate partition types */ 94*dce63815Sdrahn int pflag = PFLAG_DEFAULT; /* show physical limits of partition */ 95*dce63815Sdrahn 96*dce63815Sdrahn 97*dce63815Sdrahn // 98*dce63815Sdrahn // Forward declarations 99*dce63815Sdrahn // 100*dce63815Sdrahn void adjust_value_and_compute_prefix(double *value, int *prefix); 101*dce63815Sdrahn void dump_block_zero(partition_map_header *map); 102*dce63815Sdrahn void dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits); 103*dce63815Sdrahn int get_max_base_or_length(partition_map_header *map); 104*dce63815Sdrahn int get_max_name_string_length(partition_map_header *map); 105*dce63815Sdrahn int get_max_type_string_length(partition_map_header *map); 106*dce63815Sdrahn int strnlen(char *s, int n); 107*dce63815Sdrahn 108*dce63815Sdrahn 109*dce63815Sdrahn // 110*dce63815Sdrahn // Routines 111*dce63815Sdrahn // 112*dce63815Sdrahn int 113*dce63815Sdrahn dump(char *name) 114*dce63815Sdrahn { 115*dce63815Sdrahn partition_map_header *map; 116*dce63815Sdrahn int junk; 117*dce63815Sdrahn 118*dce63815Sdrahn map = open_partition_map(name, &junk, 0); 119*dce63815Sdrahn if (map == NULL) { 120*dce63815Sdrahn //error(-1, "No partition map in '%s'", name); 121*dce63815Sdrahn return 0; 122*dce63815Sdrahn } 123*dce63815Sdrahn 124*dce63815Sdrahn dump_partition_map(map, 1); 125*dce63815Sdrahn 126*dce63815Sdrahn close_partition_map(map); 127*dce63815Sdrahn 128*dce63815Sdrahn return 1; 129*dce63815Sdrahn } 130*dce63815Sdrahn 131*dce63815Sdrahn 132*dce63815Sdrahn void 133*dce63815Sdrahn dump_block_zero(partition_map_header *map) 134*dce63815Sdrahn { 135*dce63815Sdrahn Block0 *p; 136*dce63815Sdrahn DDMap *m; 137*dce63815Sdrahn int i; 138*dce63815Sdrahn double value; 139*dce63815Sdrahn int prefix; 140*dce63815Sdrahn 141*dce63815Sdrahn p = map->misc; 142*dce63815Sdrahn if (p->sbSig != BLOCK0_SIGNATURE) { 143*dce63815Sdrahn return; 144*dce63815Sdrahn } 145*dce63815Sdrahn 146*dce63815Sdrahn value = ((double)p->sbBlkCount) * p->sbBlkSize; 147*dce63815Sdrahn adjust_value_and_compute_prefix(&value, &prefix); 148*dce63815Sdrahn printf("\nDevice block size=%u, Number of Blocks=%lu (%1.1f%c)\n", 149*dce63815Sdrahn p->sbBlkSize, p->sbBlkCount, value, prefix); 150*dce63815Sdrahn 151*dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x\n", 152*dce63815Sdrahn p->sbDevType, p->sbDevId); 153*dce63815Sdrahn if (p->sbDrvrCount > 0) { 154*dce63815Sdrahn printf("Drivers-\n"); 155*dce63815Sdrahn m = (DDMap *) p->sbMap; 156*dce63815Sdrahn for (i = 0; i < p->sbDrvrCount; i++) { 157*dce63815Sdrahn printf("%u: @ %lu for %u, type=0x%x\n", i+1, 158*dce63815Sdrahn get_align_long(&m[i].ddBlock), 159*dce63815Sdrahn m[i].ddSize, m[i].ddType); 160*dce63815Sdrahn } 161*dce63815Sdrahn } 162*dce63815Sdrahn printf("\n"); 163*dce63815Sdrahn } 164*dce63815Sdrahn 165*dce63815Sdrahn 166*dce63815Sdrahn void 167*dce63815Sdrahn dump_partition_map(partition_map_header *map, int disk_order) 168*dce63815Sdrahn { 169*dce63815Sdrahn partition_map * entry; 170*dce63815Sdrahn int max_type_length; 171*dce63815Sdrahn int max_name_length; 172*dce63815Sdrahn int digits; 173*dce63815Sdrahn char *alternate; 174*dce63815Sdrahn 175*dce63815Sdrahn if (map == NULL) { 176*dce63815Sdrahn bad_input("No partition map exists"); 177*dce63815Sdrahn return; 178*dce63815Sdrahn } 179*dce63815Sdrahn alternate = get_mklinux_name(map->name); 180*dce63815Sdrahn if (alternate) { 181*dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s' (%s)\n", 182*dce63815Sdrahn map->logical_block, map->name, alternate); 183*dce63815Sdrahn free(alternate); 184*dce63815Sdrahn } else { 185*dce63815Sdrahn printf("\nPartition map (with %d byte blocks) on '%s'\n", 186*dce63815Sdrahn map->logical_block, map->name); 187*dce63815Sdrahn } 188*dce63815Sdrahn 189*dce63815Sdrahn digits = number_of_digits(get_max_base_or_length(map)); 190*dce63815Sdrahn if (digits < 6) { 191*dce63815Sdrahn digits = 6; 192*dce63815Sdrahn } 193*dce63815Sdrahn if (aflag) { 194*dce63815Sdrahn max_type_length = 4; 195*dce63815Sdrahn } else { 196*dce63815Sdrahn max_type_length = get_max_type_string_length(map); 197*dce63815Sdrahn if (max_type_length < 4) { 198*dce63815Sdrahn max_type_length = 4; 199*dce63815Sdrahn } 200*dce63815Sdrahn } 201*dce63815Sdrahn max_name_length = get_max_name_string_length(map); 202*dce63815Sdrahn if (max_name_length < 6) { 203*dce63815Sdrahn max_name_length = 6; 204*dce63815Sdrahn } 205*dce63815Sdrahn printf(" #: %*s %-*s %*s %-*s ( size )\n", 206*dce63815Sdrahn max_type_length, "type", 207*dce63815Sdrahn max_name_length, "name", 208*dce63815Sdrahn digits, "length", digits, "base"); 209*dce63815Sdrahn 210*dce63815Sdrahn if (disk_order) { 211*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; 212*dce63815Sdrahn entry = entry->next_on_disk) { 213*dce63815Sdrahn 214*dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 215*dce63815Sdrahn } 216*dce63815Sdrahn } else { 217*dce63815Sdrahn for (entry = map->base_order; entry != NULL; 218*dce63815Sdrahn entry = entry->next_by_base) { 219*dce63815Sdrahn 220*dce63815Sdrahn dump_partition_entry(entry, max_type_length, max_name_length, digits); 221*dce63815Sdrahn } 222*dce63815Sdrahn } 223*dce63815Sdrahn dump_block_zero(map); 224*dce63815Sdrahn } 225*dce63815Sdrahn 226*dce63815Sdrahn 227*dce63815Sdrahn void 228*dce63815Sdrahn dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits) 229*dce63815Sdrahn { 230*dce63815Sdrahn partition_map_header *map; 231*dce63815Sdrahn int j; 232*dce63815Sdrahn DPME *p; 233*dce63815Sdrahn char *s; 234*dce63815Sdrahn u32 size; 235*dce63815Sdrahn double bytes; 236*dce63815Sdrahn int driver; 237*dce63815Sdrahn 238*dce63815Sdrahn map = entry->the_map; 239*dce63815Sdrahn p = entry->data; 240*dce63815Sdrahn driver = entry->contains_driver? '*': ' '; 241*dce63815Sdrahn if (aflag) { 242*dce63815Sdrahn s = "????"; 243*dce63815Sdrahn for (j = 0; plist[j].abbr != 0; j++) { 244*dce63815Sdrahn if (strcmp(p->dpme_type, plist[j].full) == 0) { 245*dce63815Sdrahn s = plist[j].abbr; 246*dce63815Sdrahn break; 247*dce63815Sdrahn } 248*dce63815Sdrahn } 249*dce63815Sdrahn printf("%2ld: %.4s%c%-*.32s ", 250*dce63815Sdrahn entry->disk_address, s, driver, name_length, p->dpme_name); 251*dce63815Sdrahn } else { 252*dce63815Sdrahn printf("%2ld: %*.32s%c%-*.32s ", 253*dce63815Sdrahn entry->disk_address, type_length, p->dpme_type, 254*dce63815Sdrahn driver, name_length, p->dpme_name); 255*dce63815Sdrahn } 256*dce63815Sdrahn 257*dce63815Sdrahn if (pflag) { 258*dce63815Sdrahn printf("%*lu ", digits, p->dpme_pblocks); 259*dce63815Sdrahn size = p->dpme_pblocks; 260*dce63815Sdrahn } else if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) { 261*dce63815Sdrahn printf("%*lu+", digits, p->dpme_lblocks); 262*dce63815Sdrahn size = p->dpme_lblocks; 263*dce63815Sdrahn } else if (p->dpme_lblock_start != 0) { 264*dce63815Sdrahn printf("%*lu ", digits, p->dpme_lblocks); 265*dce63815Sdrahn size = p->dpme_lblocks; 266*dce63815Sdrahn } else { 267*dce63815Sdrahn printf("%*lu ", digits, p->dpme_pblocks); 268*dce63815Sdrahn size = p->dpme_pblocks; 269*dce63815Sdrahn } 270*dce63815Sdrahn if (pflag || p->dpme_lblock_start == 0) { 271*dce63815Sdrahn printf("@ %-*lu", digits, p->dpme_pblock_start); 272*dce63815Sdrahn } else { 273*dce63815Sdrahn printf("@~%-*lu", digits, p->dpme_pblock_start + p->dpme_lblock_start); 274*dce63815Sdrahn } 275*dce63815Sdrahn 276*dce63815Sdrahn bytes = ((double)size) * map->logical_block; 277*dce63815Sdrahn adjust_value_and_compute_prefix(&bytes, &j); 278*dce63815Sdrahn if (j != ' ' && j != 'K') { 279*dce63815Sdrahn printf(" (%#5.1f%c)", bytes, j); 280*dce63815Sdrahn } 281*dce63815Sdrahn 282*dce63815Sdrahn #if 0 283*dce63815Sdrahn // Old A/UX fields that no one pays attention to anymore. 284*dce63815Sdrahn bp = (BZB *) (p->dpme_bzb); 285*dce63815Sdrahn j = -1; 286*dce63815Sdrahn if (bp->bzb_magic == BZBMAGIC) { 287*dce63815Sdrahn switch (bp->bzb_type) { 288*dce63815Sdrahn case FSTEFS: 289*dce63815Sdrahn s = "EFS"; 290*dce63815Sdrahn break; 291*dce63815Sdrahn case FSTSFS: 292*dce63815Sdrahn s = "SFS"; 293*dce63815Sdrahn j = 1; 294*dce63815Sdrahn break; 295*dce63815Sdrahn case FST: 296*dce63815Sdrahn default: 297*dce63815Sdrahn if (bzb_root_get(bp) != 0) { 298*dce63815Sdrahn if (bzb_usr_get(bp) != 0) { 299*dce63815Sdrahn s = "RUFS"; 300*dce63815Sdrahn } else { 301*dce63815Sdrahn s = "RFS"; 302*dce63815Sdrahn } 303*dce63815Sdrahn j = 0; 304*dce63815Sdrahn } else if (bzb_usr_get(bp) != 0) { 305*dce63815Sdrahn s = "UFS"; 306*dce63815Sdrahn j = 2; 307*dce63815Sdrahn } else { 308*dce63815Sdrahn s = "FS"; 309*dce63815Sdrahn } 310*dce63815Sdrahn break; 311*dce63815Sdrahn } 312*dce63815Sdrahn if (bzb_slice_get(bp) != 0) { 313*dce63815Sdrahn printf(" s%1d %4s", bzb_slice_get(bp)-1, s); 314*dce63815Sdrahn } else if (j >= 0) { 315*dce63815Sdrahn printf(" S%1d %4s", j, s); 316*dce63815Sdrahn } else { 317*dce63815Sdrahn printf(" %4s", s); 318*dce63815Sdrahn } 319*dce63815Sdrahn if (bzb_crit_get(bp) != 0) { 320*dce63815Sdrahn printf(" K%1d", bp->bzb_cluster); 321*dce63815Sdrahn } else if (j < 0) { 322*dce63815Sdrahn printf(" "); 323*dce63815Sdrahn } else { 324*dce63815Sdrahn printf(" k%1d", bp->bzb_cluster); 325*dce63815Sdrahn } 326*dce63815Sdrahn if (bp->bzb_mount_point[0] != 0) { 327*dce63815Sdrahn printf(" %.64s", bp->bzb_mount_point); 328*dce63815Sdrahn } 329*dce63815Sdrahn } 330*dce63815Sdrahn #endif 331*dce63815Sdrahn printf("\n"); 332*dce63815Sdrahn } 333*dce63815Sdrahn 334*dce63815Sdrahn 335*dce63815Sdrahn void 336*dce63815Sdrahn list_all_disks() 337*dce63815Sdrahn { 338*dce63815Sdrahn MEDIA_ITERATOR iter; 339*dce63815Sdrahn MEDIA m; 340*dce63815Sdrahn DPME * data; 341*dce63815Sdrahn char *name; 342*dce63815Sdrahn long mark; 343*dce63815Sdrahn 344*dce63815Sdrahn data = (DPME *) malloc(PBLOCK_SIZE); 345*dce63815Sdrahn if (data == NULL) { 346*dce63815Sdrahn error(errno, "can't allocate memory for try buffer"); 347*dce63815Sdrahn return; 348*dce63815Sdrahn } 349*dce63815Sdrahn 350*dce63815Sdrahn for (iter = first_media_kind(&mark); iter != 0; iter = next_media_kind(&mark)) { 351*dce63815Sdrahn 352*dce63815Sdrahn while ((name = step_media_iterator(iter)) != 0) { 353*dce63815Sdrahn 354*dce63815Sdrahn if ((m = open_pathname_as_media(name, O_RDONLY)) == 0) { 355*dce63815Sdrahn error(errno, "can't open file '%s'", name); 356*dce63815Sdrahn } else { 357*dce63815Sdrahn close_media(m); 358*dce63815Sdrahn 359*dce63815Sdrahn dump(name); 360*dce63815Sdrahn } 361*dce63815Sdrahn free(name); 362*dce63815Sdrahn } 363*dce63815Sdrahn 364*dce63815Sdrahn delete_media_iterator(iter); 365*dce63815Sdrahn } 366*dce63815Sdrahn 367*dce63815Sdrahn free(data); 368*dce63815Sdrahn } 369*dce63815Sdrahn 370*dce63815Sdrahn 371*dce63815Sdrahn void 372*dce63815Sdrahn show_data_structures(partition_map_header *map) 373*dce63815Sdrahn { 374*dce63815Sdrahn Block0 *zp; 375*dce63815Sdrahn DDMap *m; 376*dce63815Sdrahn int i; 377*dce63815Sdrahn int j; 378*dce63815Sdrahn partition_map * entry; 379*dce63815Sdrahn DPME *p; 380*dce63815Sdrahn BZB *bp; 381*dce63815Sdrahn char *s; 382*dce63815Sdrahn 383*dce63815Sdrahn if (map == NULL) { 384*dce63815Sdrahn printf("No partition map exists\n"); 385*dce63815Sdrahn return; 386*dce63815Sdrahn } 387*dce63815Sdrahn printf("Header:\n"); 388*dce63815Sdrahn printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", 389*dce63815Sdrahn map->blocks_in_map, map->maximum_in_map, 390*dce63815Sdrahn map->media_size, map->logical_block); 391*dce63815Sdrahn printf("Map is%s writeable", (map->writeable)?kStringEmpty:kStringNot); 392*dce63815Sdrahn printf(", but%s changed\n", (map->changed)?kStringEmpty:kStringNot); 393*dce63815Sdrahn printf("\n"); 394*dce63815Sdrahn 395*dce63815Sdrahn if (map->misc == NULL) { 396*dce63815Sdrahn printf("No block zero\n"); 397*dce63815Sdrahn } else { 398*dce63815Sdrahn zp = map->misc; 399*dce63815Sdrahn 400*dce63815Sdrahn printf("Block0:\n"); 401*dce63815Sdrahn printf("signature 0x%x", zp->sbSig); 402*dce63815Sdrahn if (zp->sbSig == BLOCK0_SIGNATURE) { 403*dce63815Sdrahn printf("\n"); 404*dce63815Sdrahn } else { 405*dce63815Sdrahn printf(" should be 0x%x\n", BLOCK0_SIGNATURE); 406*dce63815Sdrahn } 407*dce63815Sdrahn printf("Block size=%u, Number of Blocks=%lu\n", 408*dce63815Sdrahn zp->sbBlkSize, zp->sbBlkCount); 409*dce63815Sdrahn printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%lx\n", 410*dce63815Sdrahn zp->sbDevType, zp->sbDevId, zp->sbData); 411*dce63815Sdrahn if (zp->sbDrvrCount == 0) { 412*dce63815Sdrahn printf("No drivers\n"); 413*dce63815Sdrahn } else { 414*dce63815Sdrahn printf("%u driver%s-\n", zp->sbDrvrCount, 415*dce63815Sdrahn (zp->sbDrvrCount>1)?"s":kStringEmpty); 416*dce63815Sdrahn m = (DDMap *) zp->sbMap; 417*dce63815Sdrahn for (i = 0; i < zp->sbDrvrCount; i++) { 418*dce63815Sdrahn printf("%u: @ %lu for %u, type=0x%x\n", i+1, 419*dce63815Sdrahn get_align_long(&m[i].ddBlock), 420*dce63815Sdrahn m[i].ddSize, m[i].ddType); 421*dce63815Sdrahn } 422*dce63815Sdrahn } 423*dce63815Sdrahn } 424*dce63815Sdrahn printf("\n"); 425*dce63815Sdrahn 426*dce63815Sdrahn /* 427*dce63815Sdrahn u32 dpme_boot_args[32] ; 428*dce63815Sdrahn u32 dpme_reserved_3[62] ; 429*dce63815Sdrahn */ 430*dce63815Sdrahn printf(" #: type length base " 431*dce63815Sdrahn "flags (logical)\n"); 432*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 433*dce63815Sdrahn p = entry->data; 434*dce63815Sdrahn printf("%2ld: %20.32s ", 435*dce63815Sdrahn entry->disk_address, p->dpme_type); 436*dce63815Sdrahn printf("%7lu @ %-7lu ", p->dpme_pblocks, p->dpme_pblock_start); 437*dce63815Sdrahn printf("%c%c%c%c%c%c%c%c%c%c%c%c ", 438*dce63815Sdrahn (dpme_valid_get(p))?'V':'.', 439*dce63815Sdrahn (dpme_allocated_get(p))?'A':'.', 440*dce63815Sdrahn (dpme_in_use_get(p))?'I':'.', 441*dce63815Sdrahn (dpme_bootable_get(p))?'B':'.', 442*dce63815Sdrahn (dpme_readable_get(p))?'R':'.', 443*dce63815Sdrahn (dpme_writable_get(p))?'W':'.', 444*dce63815Sdrahn (dpme_os_pic_code_get(p))?'P':'.', 445*dce63815Sdrahn (dpme_os_specific_2_get(p))?'2':'.', 446*dce63815Sdrahn (dpme_chainable_get(p))?'C':'.', 447*dce63815Sdrahn (dpme_diskdriver_get(p))?'D':'.', 448*dce63815Sdrahn (bitfield_get(p->dpme_flags, 30, 1))?'M':'.', 449*dce63815Sdrahn (bitfield_get(p->dpme_flags, 31, 1))?'X':'.'); 450*dce63815Sdrahn if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) { 451*dce63815Sdrahn printf("(%lu @ %lu)", p->dpme_lblocks, p->dpme_lblock_start); 452*dce63815Sdrahn } 453*dce63815Sdrahn printf("\n"); 454*dce63815Sdrahn } 455*dce63815Sdrahn printf("\n"); 456*dce63815Sdrahn printf(" #: booter bytes load_address " 457*dce63815Sdrahn "goto_address checksum processor\n"); 458*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 459*dce63815Sdrahn p = entry->data; 460*dce63815Sdrahn printf("%2ld: ", entry->disk_address); 461*dce63815Sdrahn printf("%7lu ", p->dpme_boot_block); 462*dce63815Sdrahn printf("%7lu ", p->dpme_boot_bytes); 463*dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr); 464*dce63815Sdrahn printf("%8lx ", (u32)p->dpme_load_addr_2); 465*dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr); 466*dce63815Sdrahn printf("%8lx ", (u32)p->dpme_goto_addr_2); 467*dce63815Sdrahn printf("%8lx ", p->dpme_checksum); 468*dce63815Sdrahn printf("%.32s", p->dpme_process_id); 469*dce63815Sdrahn printf("\n"); 470*dce63815Sdrahn } 471*dce63815Sdrahn printf("\n"); 472*dce63815Sdrahn /* 473*dce63815Sdrahn xx: cccc RU *dd s... 474*dce63815Sdrahn */ 475*dce63815Sdrahn printf(" #: type RU *slice mount_point (A/UX only fields)\n"); 476*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 477*dce63815Sdrahn p = entry->data; 478*dce63815Sdrahn printf("%2ld: ", entry->disk_address); 479*dce63815Sdrahn 480*dce63815Sdrahn bp = (BZB *) (p->dpme_bzb); 481*dce63815Sdrahn j = -1; 482*dce63815Sdrahn if (bp->bzb_magic == BZBMAGIC) { 483*dce63815Sdrahn switch (bp->bzb_type) { 484*dce63815Sdrahn case FSTEFS: 485*dce63815Sdrahn s = "esch"; 486*dce63815Sdrahn break; 487*dce63815Sdrahn case FSTSFS: 488*dce63815Sdrahn s = "swap"; 489*dce63815Sdrahn j = 1; 490*dce63815Sdrahn break; 491*dce63815Sdrahn case FST: 492*dce63815Sdrahn default: 493*dce63815Sdrahn s = "fsys"; 494*dce63815Sdrahn if (bzb_root_get(bp) != 0) { 495*dce63815Sdrahn j = 0; 496*dce63815Sdrahn } else if (bzb_usr_get(bp) != 0) { 497*dce63815Sdrahn j = 2; 498*dce63815Sdrahn } 499*dce63815Sdrahn break; 500*dce63815Sdrahn } 501*dce63815Sdrahn printf("%4s ", s); 502*dce63815Sdrahn printf("%c%c ", 503*dce63815Sdrahn (bzb_root_get(bp))?'R':' ', 504*dce63815Sdrahn (bzb_usr_get(bp))?'U':' '); 505*dce63815Sdrahn if (bzb_slice_get(bp) != 0) { 506*dce63815Sdrahn printf(" %2ld", bzb_slice_get(bp)-1); 507*dce63815Sdrahn } else if (j >= 0) { 508*dce63815Sdrahn printf(" *%2d", j); 509*dce63815Sdrahn } else { 510*dce63815Sdrahn printf(" "); 511*dce63815Sdrahn } 512*dce63815Sdrahn if (bp->bzb_mount_point[0] != 0) { 513*dce63815Sdrahn printf(" %.64s", bp->bzb_mount_point); 514*dce63815Sdrahn } 515*dce63815Sdrahn } 516*dce63815Sdrahn printf("\n"); 517*dce63815Sdrahn } 518*dce63815Sdrahn } 519*dce63815Sdrahn 520*dce63815Sdrahn 521*dce63815Sdrahn void 522*dce63815Sdrahn full_dump_partition_entry(partition_map_header *map, int index) 523*dce63815Sdrahn { 524*dce63815Sdrahn partition_map * cur; 525*dce63815Sdrahn DPME *p; 526*dce63815Sdrahn int i; 527*dce63815Sdrahn u32 t; 528*dce63815Sdrahn 529*dce63815Sdrahn cur = find_entry_by_disk_address(index, map); 530*dce63815Sdrahn if (cur == NULL) { 531*dce63815Sdrahn printf("No such partition\n"); 532*dce63815Sdrahn return; 533*dce63815Sdrahn } 534*dce63815Sdrahn 535*dce63815Sdrahn p = cur->data; 536*dce63815Sdrahn printf(" signature: 0x%x\n", p->dpme_signature); 537*dce63815Sdrahn printf(" reserved1: 0x%x\n", p->dpme_reserved_1); 538*dce63815Sdrahn printf(" number of map entries: %ld\n", p->dpme_map_entries); 539*dce63815Sdrahn printf(" physical start: %10lu length: %10lu\n", p->dpme_pblock_start, p->dpme_pblocks); 540*dce63815Sdrahn printf(" logical start: %10lu length: %10lu\n", p->dpme_lblock_start, p->dpme_lblocks); 541*dce63815Sdrahn 542*dce63815Sdrahn printf(" flags: 0x%lx\n", (u32)p->dpme_flags); 543*dce63815Sdrahn printf(" "); 544*dce63815Sdrahn if (dpme_valid_get(p)) printf("valid "); 545*dce63815Sdrahn if (dpme_allocated_get(p)) printf("alloc "); 546*dce63815Sdrahn if (dpme_in_use_get(p)) printf("in-use "); 547*dce63815Sdrahn if (dpme_bootable_get(p)) printf("boot "); 548*dce63815Sdrahn if (dpme_readable_get(p)) printf("read "); 549*dce63815Sdrahn if (dpme_writable_get(p)) printf("write "); 550*dce63815Sdrahn if (dpme_os_pic_code_get(p)) printf("pic "); 551*dce63815Sdrahn t = p->dpme_flags >> 7; 552*dce63815Sdrahn for (i = 7; i <= 31; i++) { 553*dce63815Sdrahn if (t & 0x1) { 554*dce63815Sdrahn printf("%d ", i); 555*dce63815Sdrahn } 556*dce63815Sdrahn t = t >> 1; 557*dce63815Sdrahn } 558*dce63815Sdrahn printf("\n"); 559*dce63815Sdrahn 560*dce63815Sdrahn printf(" name: '%.32s'\n", p->dpme_name); 561*dce63815Sdrahn printf(" type: '%.32s'\n", p->dpme_type); 562*dce63815Sdrahn 563*dce63815Sdrahn printf(" boot start block: %10lu\n", p->dpme_boot_block); 564*dce63815Sdrahn printf("boot length (in bytes): %10lu\n", p->dpme_boot_bytes); 565*dce63815Sdrahn printf(" load address: 0x%08lx 0x%08lx\n", 566*dce63815Sdrahn (u32)p->dpme_load_addr, (u32)p->dpme_load_addr_2); 567*dce63815Sdrahn printf(" start address: 0x%08lx 0x%08lx\n", 568*dce63815Sdrahn (u32)p->dpme_goto_addr, (u32)p->dpme_goto_addr_2); 569*dce63815Sdrahn printf(" checksum: 0x%08lx\n", p->dpme_checksum); 570*dce63815Sdrahn printf(" processor: '%.32s'\n", p->dpme_process_id); 571*dce63815Sdrahn printf("boot args field -"); 572*dce63815Sdrahn dump_block((unsigned char *)p->dpme_boot_args, 32*4); 573*dce63815Sdrahn printf("dpme_reserved_3 -"); 574*dce63815Sdrahn dump_block((unsigned char *)p->dpme_reserved_3, 62*4); 575*dce63815Sdrahn } 576*dce63815Sdrahn 577*dce63815Sdrahn 578*dce63815Sdrahn void 579*dce63815Sdrahn dump_block(unsigned char *addr, int len) 580*dce63815Sdrahn { 581*dce63815Sdrahn int i; 582*dce63815Sdrahn int j; 583*dce63815Sdrahn int limit1; 584*dce63815Sdrahn int limit; 585*dce63815Sdrahn #define LINE_LEN 16 586*dce63815Sdrahn #define UNIT_LEN 4 587*dce63815Sdrahn #define OTHER_LEN 8 588*dce63815Sdrahn 589*dce63815Sdrahn for (i = 0; i < len; i = limit) { 590*dce63815Sdrahn limit1 = i + LINE_LEN; 591*dce63815Sdrahn if (limit1 > len) { 592*dce63815Sdrahn limit = len; 593*dce63815Sdrahn } else { 594*dce63815Sdrahn limit = limit1; 595*dce63815Sdrahn } 596*dce63815Sdrahn printf("\n%03x: ", i); 597*dce63815Sdrahn for (j = i; j < limit1; j++) { 598*dce63815Sdrahn if (j % UNIT_LEN == 0) { 599*dce63815Sdrahn printf(" "); 600*dce63815Sdrahn } 601*dce63815Sdrahn if (j < limit) { 602*dce63815Sdrahn printf("%02x", addr[j]); 603*dce63815Sdrahn } else { 604*dce63815Sdrahn printf(" "); 605*dce63815Sdrahn } 606*dce63815Sdrahn } 607*dce63815Sdrahn printf(" "); 608*dce63815Sdrahn for (j = i; j < limit; j++) { 609*dce63815Sdrahn if (j % OTHER_LEN == 0) { 610*dce63815Sdrahn printf(" "); 611*dce63815Sdrahn } 612*dce63815Sdrahn if (addr[j] < ' ') { 613*dce63815Sdrahn printf("."); 614*dce63815Sdrahn } else { 615*dce63815Sdrahn printf("%c", addr[j]); 616*dce63815Sdrahn } 617*dce63815Sdrahn } 618*dce63815Sdrahn } 619*dce63815Sdrahn printf("\n"); 620*dce63815Sdrahn } 621*dce63815Sdrahn 622*dce63815Sdrahn void 623*dce63815Sdrahn full_dump_block_zero(partition_map_header *map) 624*dce63815Sdrahn { 625*dce63815Sdrahn Block0 *zp; 626*dce63815Sdrahn DDMap *m; 627*dce63815Sdrahn int i; 628*dce63815Sdrahn 629*dce63815Sdrahn if (map == NULL) { 630*dce63815Sdrahn printf("No partition map exists\n"); 631*dce63815Sdrahn return; 632*dce63815Sdrahn } 633*dce63815Sdrahn 634*dce63815Sdrahn if (map->misc == NULL) { 635*dce63815Sdrahn printf("No block zero\n"); 636*dce63815Sdrahn return; 637*dce63815Sdrahn } 638*dce63815Sdrahn zp = map->misc; 639*dce63815Sdrahn 640*dce63815Sdrahn printf(" signature: 0x%x\n", zp->sbSig); 641*dce63815Sdrahn printf(" size of a block: %d\n", zp->sbBlkSize); 642*dce63815Sdrahn printf(" number of blocks: %ld\n", zp->sbBlkCount); 643*dce63815Sdrahn printf(" device type: 0x%x\n", zp->sbDevType); 644*dce63815Sdrahn printf(" device id: 0x%x\n", zp->sbDevId); 645*dce63815Sdrahn printf(" data: 0x%lx\n", zp->sbData); 646*dce63815Sdrahn printf(" driver count: %d\n", zp->sbDrvrCount); 647*dce63815Sdrahn m = (DDMap *) zp->sbMap; 648*dce63815Sdrahn for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) { 649*dce63815Sdrahn if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) { 650*dce63815Sdrahn break; 651*dce63815Sdrahn } 652*dce63815Sdrahn printf(" driver %3u block: %ld\n", i+1, m[i].ddBlock); 653*dce63815Sdrahn printf(" size in blocks: %d\n", m[i].ddSize); 654*dce63815Sdrahn printf(" driver type: 0x%x\n", m[i].ddType); 655*dce63815Sdrahn } 656*dce63815Sdrahn printf("remainder of block -"); 657*dce63815Sdrahn dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2); 658*dce63815Sdrahn } 659*dce63815Sdrahn 660*dce63815Sdrahn void 661*dce63815Sdrahn display_patches(partition_map *entry) 662*dce63815Sdrahn { 663*dce63815Sdrahn long long offset; 664*dce63815Sdrahn MEDIA m; 665*dce63815Sdrahn static unsigned char *patch_block; 666*dce63815Sdrahn 667*dce63815Sdrahn offset = entry->data->dpme_pblock_start; 668*dce63815Sdrahn m = entry->the_map->m; 669*dce63815Sdrahn offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block; 670*dce63815Sdrahn if (patch_block == NULL) { 671*dce63815Sdrahn patch_block = (unsigned char *) malloc(PBLOCK_SIZE); 672*dce63815Sdrahn if (patch_block == NULL) { 673*dce63815Sdrahn error(errno, "can't allocate memory for patch block buffer"); 674*dce63815Sdrahn return; 675*dce63815Sdrahn } 676*dce63815Sdrahn } 677*dce63815Sdrahn if (read_media(m, (long long)offset, PBLOCK_SIZE, (char *)patch_block) == 0) { 678*dce63815Sdrahn error(errno, "Can't read patch block"); 679*dce63815Sdrahn return; 680*dce63815Sdrahn } 681*dce63815Sdrahn dump_block(patch_block, PBLOCK_SIZE); 682*dce63815Sdrahn } 683*dce63815Sdrahn 684*dce63815Sdrahn int 685*dce63815Sdrahn strnlen(char *s, int n) 686*dce63815Sdrahn { 687*dce63815Sdrahn int i; 688*dce63815Sdrahn 689*dce63815Sdrahn for (i = 0; i < n; i++) { 690*dce63815Sdrahn if (*s == 0) { 691*dce63815Sdrahn break; 692*dce63815Sdrahn } 693*dce63815Sdrahn s++; 694*dce63815Sdrahn } 695*dce63815Sdrahn return i; 696*dce63815Sdrahn } 697*dce63815Sdrahn 698*dce63815Sdrahn int 699*dce63815Sdrahn get_max_type_string_length(partition_map_header *map) 700*dce63815Sdrahn { 701*dce63815Sdrahn partition_map * entry; 702*dce63815Sdrahn int max; 703*dce63815Sdrahn int length; 704*dce63815Sdrahn 705*dce63815Sdrahn if (map == NULL) { 706*dce63815Sdrahn return 0; 707*dce63815Sdrahn } 708*dce63815Sdrahn 709*dce63815Sdrahn max = 0; 710*dce63815Sdrahn 711*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 712*dce63815Sdrahn length = strnlen(entry->data->dpme_type, DPISTRLEN); 713*dce63815Sdrahn if (length > max) { 714*dce63815Sdrahn max = length; 715*dce63815Sdrahn } 716*dce63815Sdrahn } 717*dce63815Sdrahn 718*dce63815Sdrahn return max; 719*dce63815Sdrahn } 720*dce63815Sdrahn 721*dce63815Sdrahn int 722*dce63815Sdrahn get_max_name_string_length(partition_map_header *map) 723*dce63815Sdrahn { 724*dce63815Sdrahn partition_map * entry; 725*dce63815Sdrahn int max; 726*dce63815Sdrahn int length; 727*dce63815Sdrahn 728*dce63815Sdrahn if (map == NULL) { 729*dce63815Sdrahn return 0; 730*dce63815Sdrahn } 731*dce63815Sdrahn 732*dce63815Sdrahn max = 0; 733*dce63815Sdrahn 734*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 735*dce63815Sdrahn length = strnlen(entry->data->dpme_name, DPISTRLEN); 736*dce63815Sdrahn if (length > max) { 737*dce63815Sdrahn max = length; 738*dce63815Sdrahn } 739*dce63815Sdrahn } 740*dce63815Sdrahn 741*dce63815Sdrahn return max; 742*dce63815Sdrahn } 743*dce63815Sdrahn 744*dce63815Sdrahn int 745*dce63815Sdrahn get_max_base_or_length(partition_map_header *map) 746*dce63815Sdrahn { 747*dce63815Sdrahn partition_map * entry; 748*dce63815Sdrahn int max; 749*dce63815Sdrahn 750*dce63815Sdrahn if (map == NULL) { 751*dce63815Sdrahn return 0; 752*dce63815Sdrahn } 753*dce63815Sdrahn 754*dce63815Sdrahn max = 0; 755*dce63815Sdrahn 756*dce63815Sdrahn for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) { 757*dce63815Sdrahn if (entry->data->dpme_pblock_start > max) { 758*dce63815Sdrahn max = entry->data->dpme_pblock_start; 759*dce63815Sdrahn } 760*dce63815Sdrahn if (entry->data->dpme_pblocks > max) { 761*dce63815Sdrahn max = entry->data->dpme_pblocks; 762*dce63815Sdrahn } 763*dce63815Sdrahn if (entry->data->dpme_lblock_start > max) { 764*dce63815Sdrahn max = entry->data->dpme_lblock_start; 765*dce63815Sdrahn } 766*dce63815Sdrahn if (entry->data->dpme_lblocks > max) { 767*dce63815Sdrahn max = entry->data->dpme_lblocks; 768*dce63815Sdrahn } 769*dce63815Sdrahn } 770*dce63815Sdrahn 771*dce63815Sdrahn return max; 772*dce63815Sdrahn } 773*dce63815Sdrahn 774*dce63815Sdrahn void 775*dce63815Sdrahn adjust_value_and_compute_prefix(double *value, int *prefix) 776*dce63815Sdrahn { 777*dce63815Sdrahn double bytes; 778*dce63815Sdrahn int multiplier; 779*dce63815Sdrahn 780*dce63815Sdrahn bytes = *value; 781*dce63815Sdrahn if (bytes < 1024.0) { 782*dce63815Sdrahn multiplier = ' '; 783*dce63815Sdrahn } else { 784*dce63815Sdrahn bytes = bytes / 1024.0; 785*dce63815Sdrahn if (bytes < 1024.0) { 786*dce63815Sdrahn multiplier = 'K'; 787*dce63815Sdrahn } else { 788*dce63815Sdrahn bytes = bytes / 1024.0; 789*dce63815Sdrahn if (bytes < 1024.0) { 790*dce63815Sdrahn multiplier = 'M'; 791*dce63815Sdrahn } else { 792*dce63815Sdrahn bytes = bytes / 1024.0; 793*dce63815Sdrahn if (bytes < 1024.0) { 794*dce63815Sdrahn multiplier = 'G'; 795*dce63815Sdrahn } else { 796*dce63815Sdrahn bytes = bytes / 1024.0; 797*dce63815Sdrahn multiplier = 'T'; 798*dce63815Sdrahn } 799*dce63815Sdrahn } 800*dce63815Sdrahn } 801*dce63815Sdrahn } 802*dce63815Sdrahn *value = bytes; 803*dce63815Sdrahn *prefix = multiplier; 804*dce63815Sdrahn } 805