xref: /openbsd-src/sbin/pdisk/pdisk.c (revision 52e527e9c314a74089f69978280d3c739fc91774)
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