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 |
|
|
} |