GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/fdisk/user.c Lines: 0 70 0.0 %
Date: 2016-12-06 Branches: 0 60 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: user.c,v 1.50 2016/01/09 18:10:57 krw Exp $	*/
2
3
/*
4
 * Copyright (c) 1997 Tobias Weingartner
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/fcntl.h>
21
#include <sys/disklabel.h>
22
23
#include <err.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <unistd.h>
27
28
#include "part.h"
29
#include "mbr.h"
30
#include "misc.h"
31
#include "cmd.h"
32
#include "user.h"
33
#include "gpt.h"
34
35
/* Our command table */
36
struct cmd cmd_table[] = {
37
	{"help",   1, Xhelp,   "Command help list"},
38
	{"manual", 1, Xmanual, "Show entire OpenBSD man page for fdisk"},
39
	{"reinit", 1, Xreinit, "Re-initialize loaded MBR (to defaults)"},
40
	{"setpid", 1, Xsetpid, "Set the identifier of a given table entry"},
41
	{"disk",   0, Xdisk,   "Edit current drive stats"},
42
	{"edit",   1, Xedit,   "Edit given table entry"},
43
	{"flag",   1, Xflag,   "Flag given table entry as bootable"},
44
	{"update", 0, Xupdate, "Update machine code in loaded MBR"},
45
	{"select", 0, Xselect, "Select extended partition table entry MBR"},
46
	{"swap",   1, Xswap,   "Swap two partition entries"},
47
	{"print",  1, Xprint,  "Print loaded MBR partition table"},
48
	{"write",  1, Xwrite,  "Write loaded MBR to disk"},
49
	{"exit",   1, Xexit,   "Exit edit of current MBR, without saving changes"},
50
	{"quit",   1, Xquit,   "Quit edit of current MBR, saving current changes"},
51
	{"abort",  1, Xabort,  "Abort program without saving current changes"},
52
	{NULL,     0, NULL,    NULL}
53
};
54
55
56
int modified;
57
58
void
59
USER_edit(off_t offset, off_t reloff)
60
{
61
	static int editlevel;
62
	struct dos_mbr dos_mbr;
63
	struct mbr mbr;
64
	char *cmd, *args;
65
	int i, st, error;
66
67
	/* One level deeper */
68
	editlevel += 1;
69
70
	/* Read MBR & partition */
71
	error = MBR_read(offset, &dos_mbr);
72
	if (error == -1)
73
		goto done;
74
75
	/* Parse the sucker */
76
	MBR_parse(&dos_mbr, offset, reloff, &mbr);
77
78
	if (editlevel == 1) {
79
		memset(&gh, 0, sizeof(gh));
80
		memset(&gp, 0, sizeof(gp));
81
		if (MBR_protective_mbr(&mbr) == 0)
82
			GPT_get_gpt(0);
83
	}
84
85
	printf("Enter 'help' for information\n");
86
87
	/* Edit cycle */
88
again:
89
	do {
90
		printf("fdisk:%c%d> ", (modified)?'*':' ', editlevel);
91
		fflush(stdout);
92
		ask_cmd(&cmd, &args);
93
94
		if (cmd[0] == '\0')
95
			continue;
96
		for (i = 0; cmd_table[i].cmd != NULL; i++)
97
			if (strstr(cmd_table[i].cmd, cmd) == cmd_table[i].cmd)
98
				break;
99
100
		/* Quick hack to put in '?' == 'help' */
101
		if (!strcmp(cmd, "?"))
102
			i = 0;
103
104
		/* Check for valid command */
105
		if ((cmd_table[i].cmd == NULL) || (letoh64(gh.gh_sig) ==
106
		    GPTSIGNATURE && cmd_table[i].gpt == 0)) {
107
			printf("Invalid command '%s'.  Try 'help'.\n", cmd);
108
			continue;
109
		}
110
111
		/* Call function */
112
		st = cmd_table[i].fcn(args, &mbr);
113
114
		/* Update status */
115
		if (st == CMD_EXIT)
116
			break;
117
		if (st == CMD_SAVE)
118
			break;
119
		if (st == CMD_CLEAN)
120
			modified = 0;
121
		if (st == CMD_DIRTY)
122
			modified = 1;
123
	} while (1);
124
125
	/* Write out MBR */
126
	if (modified) {
127
		if (st == CMD_SAVE) {
128
			if (Xwrite(NULL, &mbr) == CMD_CONT)
129
				goto again;
130
		} else
131
			printf("Aborting changes to current MBR.\n");
132
	}
133
134
done:
135
	/* One level less */
136
	editlevel -= 1;
137
}
138
139
void
140
USER_print_disk(int verbosity)
141
{
142
	off_t offset, firstoff;
143
	int i, error;
144
	struct dos_mbr dos_mbr;
145
	struct mbr mbr;
146
147
	offset = firstoff = 0;
148
149
	do {
150
		error = MBR_read(offset, &dos_mbr);
151
		if (error == -1)
152
			break;
153
		MBR_parse(&dos_mbr, offset, firstoff, &mbr);
154
		if (offset == 0) {
155
		       if (verbosity || MBR_protective_mbr(&mbr) == 0) {
156
				if (verbosity) {
157
					printf("Primary GPT:\n");
158
					GPT_get_gpt(1); /* Get Primary */
159
				}
160
				if (letoh64(gh.gh_sig) == GPTSIGNATURE)
161
					GPT_print("s", verbosity);
162
				else
163
					printf("\tNot Found\n");
164
				if (verbosity) {
165
					printf("\n");
166
					printf("Secondary GPT:\n");
167
					GPT_get_gpt(2); /* Get Secondary */
168
					if (letoh64(gh.gh_sig) == GPTSIGNATURE)
169
						GPT_print("s", verbosity);
170
					else
171
						printf("\tNot Found\n");
172
					printf("\nMBR:\n");
173
				} else
174
					break;
175
		       }
176
		}
177
178
		MBR_print(&mbr, NULL);
179
180
		/* Print out extended partitions too */
181
		for (offset = i = 0; i < 4; i++)
182
			if (mbr.part[i].id == DOSPTYP_EXTEND ||
183
			    mbr.part[i].id == DOSPTYP_EXTENDL) {
184
				offset = (off_t)mbr.part[i].bs;
185
				if (firstoff == 0)
186
					firstoff = offset;
187
			}
188
	} while (offset);
189
}