xref: /openbsd/sbin/pdisk/dump.c (revision dce63815)
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