1*52e527e9Stb /* $OpenBSD: pdisk.c,v 1.87 2016/05/28 22:26:13 tb Exp $ */
2fb04e59aSjasper
386ec409aSkrw /*
486ec409aSkrw * pdisk - an editor for Apple format partition tables
586ec409aSkrw *
686ec409aSkrw * Written by Eryk Vershen
786ec409aSkrw *
886ec409aSkrw * Still under development (as of 15 January 1998)
986ec409aSkrw */
10dce63815Sdrahn
11dce63815Sdrahn /*
12dce63815Sdrahn * Copyright 1996,1997,1998 by Apple Computer, Inc.
13dce63815Sdrahn * All Rights Reserved
14dce63815Sdrahn *
15dce63815Sdrahn * Permission to use, copy, modify, and distribute this software and
16dce63815Sdrahn * its documentation for any purpose and without fee is hereby granted,
17dce63815Sdrahn * provided that the above copyright notice appears in all copies and
18dce63815Sdrahn * that both the copyright notice and this permission notice appear in
19dce63815Sdrahn * supporting documentation.
20dce63815Sdrahn *
21dce63815Sdrahn * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
22dce63815Sdrahn * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23dce63815Sdrahn * FOR A PARTICULAR PURPOSE.
24dce63815Sdrahn *
25dce63815Sdrahn * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
26dce63815Sdrahn * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
27dce63815Sdrahn * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
28dce63815Sdrahn * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
29dce63815Sdrahn * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30dce63815Sdrahn */
31dce63815Sdrahn
32f7e12bbcSkrw #include <sys/param.h> /* DEV_BSIZE */
3336bbc7f2Skrw #include <sys/dkio.h>
3436bbc7f2Skrw #include <sys/disklabel.h>
3536bbc7f2Skrw #include <sys/ioctl.h>
360392b273Skrw #include <sys/queue.h>
3736bbc7f2Skrw #include <sys/stat.h>
3868d0f91bSkrw
3936bbc7f2Skrw #include <err.h>
4036bbc7f2Skrw #include <fcntl.h>
41dce63815Sdrahn #include <stdio.h>
42dce63815Sdrahn #include <stdlib.h>
43dce63815Sdrahn #include <string.h>
4436bbc7f2Skrw #include <unistd.h>
4536bbc7f2Skrw #include <util.h>
46dce63815Sdrahn
47dce63815Sdrahn #include "partition_map.h"
48a63f2390Skrw #include "io.h"
49dce63815Sdrahn #include "dump.h"
50dce63815Sdrahn
51d6fd5d72Skrw int lflag; /* list the device */
52d6fd5d72Skrw int rflag; /* open device read Only */
53dce63815Sdrahn
54dce63815Sdrahn static int first_get = 1;
55dce63815Sdrahn
560bd33b2aSkrw void do_dump_map(struct partition_map *, int);
57356b92ceSkrw void do_change_map_size(struct partition_map *);
58356b92ceSkrw void do_create_partition(struct partition_map *, int);
59356b92ceSkrw void do_delete_partition(struct partition_map *);
60356b92ceSkrw void do_display_entry(struct partition_map *);
61356b92ceSkrw void do_rename_partition(struct partition_map *);
62356b92ceSkrw void do_change_type(struct partition_map *);
63356b92ceSkrw void do_reorder(struct partition_map *);
64356b92ceSkrw void do_write_partition_map(struct partition_map *);
65356b92ceSkrw void edit(struct partition_map **);
66356b92ceSkrw int get_base_argument(long *, struct partition_map *);
67356b92ceSkrw int get_size_argument(long *, struct partition_map *);
68dce63815Sdrahn
6968d0f91bSkrw __dead static void usage(void);
70dce63815Sdrahn
71dce63815Sdrahn int
main(int argc,char ** argv)72dce63815Sdrahn main(int argc, char **argv)
73dce63815Sdrahn {
7436bbc7f2Skrw struct disklabel dl;
7536bbc7f2Skrw struct stat st;
76356b92ceSkrw struct partition_map *map;
77629cc629Skrw int c, fd, oflags;
78dce63815Sdrahn
79629cc629Skrw oflags = O_RDWR;
809c148747Skrw while ((c = getopt(argc, argv, "lr")) != -1) {
81d6fd5d72Skrw switch (c) {
82d6fd5d72Skrw case 'l':
83d6fd5d72Skrw lflag = 1;
84629cc629Skrw oflags = O_RDONLY;
85d6fd5d72Skrw break;
86d6fd5d72Skrw case 'r':
87d6fd5d72Skrw rflag = 1;
88629cc629Skrw oflags = O_RDONLY;
89d6fd5d72Skrw break;
90d6fd5d72Skrw default:
91d6fd5d72Skrw usage();
92d6fd5d72Skrw break;
93d6fd5d72Skrw }
94d6fd5d72Skrw }
95d6fd5d72Skrw
96d3e64b80Skrw argc -= optind;
97d3e64b80Skrw argv += optind;
98d3e64b80Skrw
99d3e64b80Skrw if (argc != 1)
100d3e64b80Skrw usage();
101dce63815Sdrahn
102629cc629Skrw fd = opendev(*argv, oflags, OPENDEV_PART, NULL);
10336bbc7f2Skrw if (fd == -1)
10436bbc7f2Skrw err(1, "can't open file '%s'", *argv);
105871f9be1Skrw
10636bbc7f2Skrw if (fstat(fd, &st) == -1)
10736bbc7f2Skrw err(1, "can't fstat %s", *argv);
1080a9d837bSkrw if (!S_ISCHR(st.st_mode))
1090a9d837bSkrw errx(1, "%s is not a character device", *argv);
110871f9be1Skrw
11136bbc7f2Skrw if (ioctl(fd, DIOCGPDINFO, &dl) == -1)
11236bbc7f2Skrw err(1, "can't get disklabel for %s", *argv);
113f7e12bbcSkrw if (dl.d_secsize != DEV_BSIZE)
114f7e12bbcSkrw errx(1, "disk sector size (%d) != 512\n", dl.d_secsize);
1157e2ef4a3Skrw
116871f9be1Skrw if (pledge("stdio", NULL) == -1)
117871f9be1Skrw err(1, "pledge");
118871f9be1Skrw
119edde6c52Skrw map = open_partition_map(fd, *argv, DL_GETDSIZE(&dl), dl.d_secsize);
1207e2ef4a3Skrw if (map != NULL) {
12136bbc7f2Skrw if (lflag)
1229c148747Skrw dump_partition_map(map);
12336bbc7f2Skrw else
12436bbc7f2Skrw edit(&map);
125dce63815Sdrahn }
12636bbc7f2Skrw
12736bbc7f2Skrw free_partition_map(map);
12836bbc7f2Skrw close(fd);
129d3e64b80Skrw
130dce63815Sdrahn return 0;
131dce63815Sdrahn }
132dce63815Sdrahn
13386ec409aSkrw /*
13486ec409aSkrw * Edit the file
13586ec409aSkrw */
136dce63815Sdrahn void
edit(struct partition_map ** mapp)137356b92ceSkrw edit(struct partition_map **mapp)
138dce63815Sdrahn {
139356b92ceSkrw struct partition_map *map = *mapp;
140356b92ceSkrw struct partition_map *oldmap;
14136bbc7f2Skrw int command;
142dce63815Sdrahn
14336bbc7f2Skrw printf("Edit %s -\n", map->name);
144dce63815Sdrahn
145dce63815Sdrahn while (get_command("Command (? for help): ", first_get, &command)) {
146dce63815Sdrahn first_get = 0;
147dce63815Sdrahn
148dce63815Sdrahn switch (command) {
149dce63815Sdrahn case '?':
1509c148747Skrw printf("Notes:\n"
1519c148747Skrw " Base and length fields are blocks, which "
1529c148747Skrw "vary in size between media.\n"
1539c148747Skrw " The base field can be <nth>p; i.e. the "
1549c148747Skrw "base of the nth partition.\n"
1559c148747Skrw " The length field can be a length followed "
1569c148747Skrw "by k, m, g or t to indicate\n"
1579c148747Skrw " kilo, mega, giga, or tera bytes.\n"
1589c148747Skrw " The length field can also be <nth>p; i.e. "
1599c148747Skrw "the length of the nth partition.\n"
1609c148747Skrw " The name of a partition is descriptive "
1619c148747Skrw "text.\n\n");
1629c148747Skrw
16386ec409aSkrw /* fall through */
164dce63815Sdrahn case 'h':
1659c148747Skrw printf("Commands are:\n"
1669c148747Skrw " ? verbose command help\n"
16796a612b0Skrw " C create a partition of a specified type\n"
1689c148747Skrw " c create an OpenBSD partition\n"
1699c148747Skrw " d delete a partition\n"
17096a612b0Skrw " f full display of a partition\n"
1719c148747Skrw " h command help\n"
1729c148747Skrw " i (re)initialize the partition map\n"
1739c148747Skrw " n (re)name a partition\n"
1749c148747Skrw " P show the partition map's data structures\n"
1759c148747Skrw " p print the partition map\n"
1769c148747Skrw " q quit editing\n"
177d9e7eca0Skrw " r reorder (swap) disk positions of two "
178d9e7eca0Skrw "entries in the partition map\n"
1799c148747Skrw " s change the size of the partition map\n"
18096a612b0Skrw " t change the type of a partition\n"
18196a612b0Skrw " w write the partition map to disk\n");
182dce63815Sdrahn break;
183dce63815Sdrahn case 'P':
1840bd33b2aSkrw do_dump_map(map, 1);
185c0b5a6c2Skrw break;
186dce63815Sdrahn case 'p':
1870bd33b2aSkrw do_dump_map(map, 0);
188dce63815Sdrahn break;
189dce63815Sdrahn case 'q':
19036bbc7f2Skrw if (map->changed) {
19130c6b2d6Skrw if (get_okay("Discard changes? [n/y]: ", 0) !=
19230c6b2d6Skrw 1) {
193b42d9302Smartin break;
194b42d9302Smartin }
195b42d9302Smartin }
196dce63815Sdrahn flush_to_newline(1);
19736bbc7f2Skrw return;
198dce63815Sdrahn case 'i':
19936bbc7f2Skrw if (get_okay("Discard current map? [n/y]: ", 0) == 1) {
20036bbc7f2Skrw oldmap = map;
20136bbc7f2Skrw map = create_partition_map(oldmap->fd,
202edde6c52Skrw oldmap->name, oldmap->media_size,
203ead46a34Skrw oldmap->sbBlkSize);
20436bbc7f2Skrw if (map == NULL)
20536bbc7f2Skrw break;
20636bbc7f2Skrw *mapp = map;
20736bbc7f2Skrw free_partition_map(oldmap);
20836bbc7f2Skrw }
209dce63815Sdrahn break;
210dce63815Sdrahn case 'C':
211c0b5a6c2Skrw do_create_partition(map, 1);
212c0b5a6c2Skrw break;
213dce63815Sdrahn case 'c':
214c0b5a6c2Skrw do_create_partition(map, 0);
215dce63815Sdrahn break;
216dce63815Sdrahn case 'n':
217dce63815Sdrahn do_rename_partition(map);
218dce63815Sdrahn break;
219dce63815Sdrahn case 'd':
220dce63815Sdrahn do_delete_partition(map);
221dce63815Sdrahn break;
222dce63815Sdrahn case 'r':
223dce63815Sdrahn do_reorder(map);
224dce63815Sdrahn break;
225dce63815Sdrahn case 's':
226dce63815Sdrahn do_change_map_size(map);
227dce63815Sdrahn break;
2281faa4e16Sdrahn case 't':
2291faa4e16Sdrahn do_change_type(map);
2301faa4e16Sdrahn break;
231dce63815Sdrahn case 'w':
232dce63815Sdrahn do_write_partition_map(map);
233dce63815Sdrahn break;
2349c148747Skrw case 'f':
2359c148747Skrw do_display_entry(map);
2369c148747Skrw break;
237dce63815Sdrahn default:
238dce63815Sdrahn bad_input("No such command (%c)", command);
239dce63815Sdrahn break;
240dce63815Sdrahn }
241dce63815Sdrahn }
242dce63815Sdrahn }
243dce63815Sdrahn
244dce63815Sdrahn void
do_create_partition(struct partition_map * map,int get_type)245356b92ceSkrw do_create_partition(struct partition_map *map, int get_type)
246dce63815Sdrahn {
24730c6b2d6Skrw long base, length;
24830c6b2d6Skrw char *name = NULL;
2498799a2d3Skrw char *type = NULL;
250dce63815Sdrahn
2518799a2d3Skrw if (get_base_argument(&base, map) == 0)
252dce63815Sdrahn return;
2538799a2d3Skrw if (get_size_argument(&length, map) == 0)
254dce63815Sdrahn return;
2558799a2d3Skrw
2568799a2d3Skrw name = get_dpistr_argument("Name of partition: ");
2578799a2d3Skrw if (name == NULL) {
258dce63815Sdrahn bad_input("Bad name");
2598799a2d3Skrw goto out;
260dce63815Sdrahn }
2618799a2d3Skrw
2628799a2d3Skrw if (get_type == 0)
2638799a2d3Skrw type = strdup(kUnixType);
2648799a2d3Skrw else
2658799a2d3Skrw type = get_dpistr_argument("Type of partition: ");
2668799a2d3Skrw if (type == NULL) {
267dce63815Sdrahn bad_input("Bad type");
2688799a2d3Skrw goto out;
269dce63815Sdrahn }
2708799a2d3Skrw
2718799a2d3Skrw if (strncasecmp(type, kFreeType, DPISTRLEN) == 0) {
2728799a2d3Skrw bad_input("Can't create a partition with the Free type");
2738799a2d3Skrw goto out;
274dce63815Sdrahn }
2758799a2d3Skrw if (strncasecmp(type, kMapType, DPISTRLEN) == 0) {
2768799a2d3Skrw bad_input("Can't create a partition with the Map type");
2778799a2d3Skrw goto out;
278b42d9302Smartin }
2798799a2d3Skrw
2808799a2d3Skrw add_partition_to_map(name, type, base, length, map);
2818799a2d3Skrw
2828799a2d3Skrw out:
2838799a2d3Skrw free(type);
284dce63815Sdrahn free(name);
2858799a2d3Skrw
286dce63815Sdrahn return;
287dce63815Sdrahn }
288dce63815Sdrahn
289dce63815Sdrahn int
get_base_argument(long * number,struct partition_map * map)290356b92ceSkrw get_base_argument(long *number, struct partition_map *map)
291dce63815Sdrahn {
292356b92ceSkrw struct entry *entry;
293dce63815Sdrahn int result = 0;
294dce63815Sdrahn
29567ac1252Skrw if (get_number_argument("First block: ", number) == 0) {
296dce63815Sdrahn bad_input("Bad block number");
297dce63815Sdrahn } else {
298dce63815Sdrahn result = 1;
299dce63815Sdrahn if (get_partition_modifier()) {
300dce63815Sdrahn entry = find_entry_by_disk_address(*number, map);
301dce63815Sdrahn if (entry == NULL) {
302dce63815Sdrahn bad_input("Bad partition number");
303dce63815Sdrahn result = 0;
304dce63815Sdrahn } else {
305f8fa35e5Skrw *number = entry->dpme_pblock_start;
306dce63815Sdrahn }
307dce63815Sdrahn }
308dce63815Sdrahn }
309dce63815Sdrahn return result;
310dce63815Sdrahn }
311dce63815Sdrahn
312dce63815Sdrahn
313dce63815Sdrahn int
get_size_argument(long * number,struct partition_map * map)314356b92ceSkrw get_size_argument(long *number, struct partition_map *map)
315dce63815Sdrahn {
316356b92ceSkrw struct entry *entry;
317dce63815Sdrahn unsigned long multiple;
31830c6b2d6Skrw int result = 0;
319dce63815Sdrahn
32067ac1252Skrw if (get_number_argument("Length in blocks: ", number) == 0) {
321dce63815Sdrahn bad_input("Bad length");
322dce63815Sdrahn } else {
323ead46a34Skrw multiple = get_multiplier(map->sbBlkSize);
324dce63815Sdrahn if (multiple == 0) {
325dce63815Sdrahn bad_input("Bad multiplier");
326dce63815Sdrahn } else if (multiple != 1) {
327dce63815Sdrahn *number *= multiple;
328dce63815Sdrahn result = 1;
329dce63815Sdrahn } else if (get_partition_modifier()) {
330dce63815Sdrahn entry = find_entry_by_disk_address(*number, map);
331dce63815Sdrahn if (entry == NULL) {
332dce63815Sdrahn bad_input("Bad partition number");
333dce63815Sdrahn } else {
334f8fa35e5Skrw *number = entry->dpme_pblocks;
335dce63815Sdrahn result = 1;
336dce63815Sdrahn }
337dce63815Sdrahn } else {
338dce63815Sdrahn result = 1;
339dce63815Sdrahn }
340dce63815Sdrahn }
341dce63815Sdrahn return result;
342dce63815Sdrahn }
343dce63815Sdrahn
344dce63815Sdrahn
345dce63815Sdrahn void
do_rename_partition(struct partition_map * map)346356b92ceSkrw do_rename_partition(struct partition_map *map)
347dce63815Sdrahn {
348356b92ceSkrw struct entry *entry;
349dce63815Sdrahn char *name;
35030c6b2d6Skrw long ix;
351dce63815Sdrahn
35267ac1252Skrw if (get_number_argument("Partition number: ", &ix) == 0) {
353dce63815Sdrahn bad_input("Bad partition number");
354dce63815Sdrahn return;
355dce63815Sdrahn }
356b42d9302Smartin entry = find_entry_by_disk_address(ix, map);
357dce63815Sdrahn if (entry == NULL) {
358dce63815Sdrahn printf("No such partition\n");
3598799a2d3Skrw return;
3608799a2d3Skrw }
3618799a2d3Skrw
362f8fa35e5Skrw printf("Existing partition name ``%s''.\n", entry->dpme_name);
3638799a2d3Skrw name = get_dpistr_argument("New name of partition: ");
3648799a2d3Skrw if (name == NULL) {
3658799a2d3Skrw bad_input("Bad name");
3668799a2d3Skrw return;
3678799a2d3Skrw }
3688799a2d3Skrw
36938bdfd73Skrw /*
37038bdfd73Skrw * Since dpme_name is supposed to be NUL-filled, make sure
37138bdfd73Skrw * current contents are zapped before copying in new name!
37238bdfd73Skrw */
373f8fa35e5Skrw memset(entry->dpme_name, 0, sizeof(entry->dpme_name));
374f8fa35e5Skrw strlcpy(entry->dpme_name, name, sizeof(entry->dpme_name));
375dce63815Sdrahn map->changed = 1;
3768799a2d3Skrw
377dce63815Sdrahn free(name);
378dce63815Sdrahn return;
379dce63815Sdrahn }
380dce63815Sdrahn
3811faa4e16Sdrahn void
do_change_type(struct partition_map * map)382356b92ceSkrw do_change_type(struct partition_map *map)
3831faa4e16Sdrahn {
384356b92ceSkrw struct entry *entry;
3858799a2d3Skrw char *type;
38630c6b2d6Skrw long ix;
3871faa4e16Sdrahn
38867ac1252Skrw if (get_number_argument("Partition number: ", &ix) == 0) {
3891faa4e16Sdrahn bad_input("Bad partition number");
3901faa4e16Sdrahn return;
3911faa4e16Sdrahn }
392b42d9302Smartin entry = find_entry_by_disk_address(ix, map);
3931faa4e16Sdrahn if (entry == NULL) {
3941faa4e16Sdrahn printf("No such partition\n");
3958799a2d3Skrw return;
3961faa4e16Sdrahn }
3978799a2d3Skrw
398f8fa35e5Skrw printf("Existing partition type ``%s''.\n", entry->dpme_type);
3998799a2d3Skrw type = get_dpistr_argument("New type of partition: ");
4008799a2d3Skrw if (type == NULL) {
4011faa4e16Sdrahn bad_input("Bad type");
4028799a2d3Skrw return;
4031faa4e16Sdrahn }
4048799a2d3Skrw
40538bdfd73Skrw /*
40638bdfd73Skrw * Since dpme_type is supposed to be NUL-filled, make sure
40738bdfd73Skrw * current contents are zapped before copying in new type!
40838bdfd73Skrw */
409f8fa35e5Skrw memset(entry->dpme_type, 0, sizeof(entry->dpme_type));
410f8fa35e5Skrw strncpy(entry->dpme_type, type, sizeof(entry->dpme_type));
4111faa4e16Sdrahn map->changed = 1;
4121faa4e16Sdrahn
4131faa4e16Sdrahn free(type);
4141faa4e16Sdrahn return;
4151faa4e16Sdrahn }
4161faa4e16Sdrahn
417dce63815Sdrahn
418dce63815Sdrahn void
do_delete_partition(struct partition_map * map)419356b92ceSkrw do_delete_partition(struct partition_map *map)
420dce63815Sdrahn {
421356b92ceSkrw struct entry *cur;
422b42d9302Smartin long ix;
423dce63815Sdrahn
42467ac1252Skrw if (get_number_argument("Partition number: ", &ix) == 0) {
425dce63815Sdrahn bad_input("Bad partition number");
426dce63815Sdrahn return;
427dce63815Sdrahn }
428a8b53b4cSkrw
429b42d9302Smartin cur = find_entry_by_disk_address(ix, map);
430a8b53b4cSkrw if (cur == NULL)
431dce63815Sdrahn printf("No such partition\n");
432a8b53b4cSkrw else
433dce63815Sdrahn delete_partition_from_map(cur);
434dce63815Sdrahn }
435dce63815Sdrahn
436dce63815Sdrahn
437dce63815Sdrahn void
do_reorder(struct partition_map * map)438356b92ceSkrw do_reorder(struct partition_map *map)
439dce63815Sdrahn {
44030c6b2d6Skrw long ix, old_index;
441dce63815Sdrahn
44267ac1252Skrw if (get_number_argument("Partition number: ", &old_index) == 0) {
443dce63815Sdrahn bad_input("Bad partition number");
444dce63815Sdrahn return;
445dce63815Sdrahn }
44667ac1252Skrw if (get_number_argument("New number: ", &ix) == 0) {
447dce63815Sdrahn bad_input("Bad partition number");
448dce63815Sdrahn return;
449dce63815Sdrahn }
450b42d9302Smartin move_entry_in_map(old_index, ix, map);
451dce63815Sdrahn }
452dce63815Sdrahn
453dce63815Sdrahn
454dce63815Sdrahn void
do_write_partition_map(struct partition_map * map)455356b92ceSkrw do_write_partition_map(struct partition_map *map)
456dce63815Sdrahn {
45775352458Skrw if (map->changed == 0) {
458dce63815Sdrahn bad_input("The map has not been changed.");
459dce63815Sdrahn return;
460dce63815Sdrahn }
46163fd5e9bSkrw if (rflag) {
46228a189edShenning bad_input("The map is not writable.");
463dce63815Sdrahn return;
464dce63815Sdrahn }
465dce63815Sdrahn printf("Writing the map destroys what was there before. ");
466dce63815Sdrahn if (get_okay("Is that okay? [n/y]: ", 0) != 1) {
467dce63815Sdrahn return;
468dce63815Sdrahn }
469dce63815Sdrahn write_partition_map(map);
470dce63815Sdrahn
471b42d9302Smartin map->changed = 0;
472dce63815Sdrahn }
473dce63815Sdrahn
474dce63815Sdrahn
475dce63815Sdrahn void
do_change_map_size(struct partition_map * map)476356b92ceSkrw do_change_map_size(struct partition_map *map)
477dce63815Sdrahn {
478dce63815Sdrahn long size;
479dce63815Sdrahn
48067ac1252Skrw if (get_number_argument("New size: ", &size) == 0) {
481dce63815Sdrahn bad_input("Bad size");
482dce63815Sdrahn return;
483dce63815Sdrahn }
484dce63815Sdrahn resize_map(size, map);
485dce63815Sdrahn }
486dce63815Sdrahn
487dce63815Sdrahn
488dce63815Sdrahn void
do_display_entry(struct partition_map * map)489356b92ceSkrw do_display_entry(struct partition_map *map)
490dce63815Sdrahn {
491dce63815Sdrahn long number;
492dce63815Sdrahn
49367ac1252Skrw if (get_number_argument("Partition number: ", &number) == 0) {
494dce63815Sdrahn bad_input("Bad partition number");
495dce63815Sdrahn return;
496dce63815Sdrahn }
497a8b53b4cSkrw if (number == 0)
498dce63815Sdrahn full_dump_block_zero(map);
499a8b53b4cSkrw else
500dce63815Sdrahn full_dump_partition_entry(map, number);
501dce63815Sdrahn }
502dce63815Sdrahn
5030bd33b2aSkrw void
do_dump_map(struct partition_map * map,int verbose)5040bd33b2aSkrw do_dump_map(struct partition_map *map, int verbose)
5050bd33b2aSkrw {
5060bd33b2aSkrw if (verbose)
5070bd33b2aSkrw show_data_structures(map);
5080bd33b2aSkrw else
5090bd33b2aSkrw dump_partition_map(map);
5100bd33b2aSkrw }
511dce63815Sdrahn
51268d0f91bSkrw __dead static void
usage(void)51368d0f91bSkrw usage(void)
51468d0f91bSkrw {
51568d0f91bSkrw extern char *__progname;
51668d0f91bSkrw
51768d0f91bSkrw fprintf(stderr, "usage: %s [-lr] disk\n", __progname);
51868d0f91bSkrw
51968d0f91bSkrw exit(1);
52068d0f91bSkrw }
521