source: mainline/uspace/app/hdisk/hdisk.c@ 622a50b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 622a50b was 622a50b, checked in by Dominik Taborsky (AT DOT) <brembyseznamcz>, 12 years ago

Jiri Svoboda credits

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2012, 2013 Dominik Taborsky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /** @addtogroup hdisk
30 * @{
31 */
32/** @file
33 */
34
35#include <ipc/bd.h>
36#include <loc.h>
37#include <async.h>
38#include <stdio.h>
39#include <ipc/services.h>
40#include <block.h>
41#include <errno.h>
42#include <stdlib.h>
43#include <assert.h>
44#include <str.h>
45#include <libmbr.h>
46#include <libgpt.h>
47#include <tinput.h>
48
49#include "hdisk.h"
50#include "input.h"
51#include "func_gpt.h"
52#include "func_mbr.h"
53#include "func_none.h"
54
55int interact(service_id_t dev_handle);
56void print_help(void);
57void select_table_format(tinput_t * in);
58void fill_table_funcs(void);
59void free_table(void);
60
61static table_t table;
62
63int main(int argc, char ** argv)
64{
65 if (argc == 1) {
66 printf("I'd like to have an argument, please.\n");
67 return 1;
68 }
69
70 int rc;
71 service_id_t dev_handle;
72
73 rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
74 if (rc != EOK) {
75 printf("Unknown device. Exiting.\n");
76 return -1;
77 }
78
79 init_table();
80
81 mbr_t * mbr = mbr_read_mbr(dev_handle);
82 if(mbr == NULL) {
83 printf("Failed to read the Master Boot Record.\n" \
84 "Either memory allocation or disk access failed. Exiting.\n");
85 return -1;
86 }
87
88 if(mbr_is_mbr(mbr)) {
89 table.layout = LYT_MBR;
90 set_table_mbr(mbr);
91 mbr_partitions_t * parts = mbr_read_partitions(mbr);
92 if(parts == NULL) {
93 printf("Failed to read and parse partitions.\n" \
94 "Creating new partition table.");
95 parts = mbr_alloc_partitions();
96 }
97 set_table_mbr_parts(parts);
98 fill_table_funcs();
99 goto interact;
100 }
101
102
103 mbr_free_mbr(mbr);
104 gpt_t * gpt = gpt_read_gpt_header(dev_handle);
105
106 if(gpt != NULL) {
107 table.layout = LYT_GPT;
108 set_table_gpt(gpt);
109
110 gpt_partitions_t * parts = gpt_read_partitions(gpt);
111
112 if(parts == NULL) {
113 printf("Failed to read and parse partitions.\n" \
114 "Creating new partition table.");
115 parts = gpt_alloc_partitions();
116 }
117 set_table_gpt_parts(parts);
118 fill_table_funcs();
119 goto interact;
120 }
121 printf("No partition table recognized. Create a new one.\n");
122 table.layout = LYT_NONE;
123
124interact:
125 rc = interact(dev_handle);
126
127 free_table();
128
129 return rc;
130}
131
132/** Interact with user */
133int interact(service_id_t dev_handle)
134{
135 int input;
136 tinput_t * in;
137
138 in = tinput_new();
139 if (in == NULL) {
140 printf("Failed initing input. Free some memory.\n");
141 return ENOMEM;
142 }
143 tinput_set_prompt(in, "");
144
145 printf("Welcome to hdisk.\nType 'h' for help.\n");
146
147 while (1) {
148 printf("# ");
149 input = getchar();
150 printf("%c\n", input);
151
152 switch(input) {
153 case 'a':
154 table.add_part(in, &table.data);
155 break;
156 case 'd':
157 table.delete_part(in, &table.data);
158 break;
159 case 'e':
160 table.extra_funcs(in, dev_handle, &table.data);
161 break;
162 case 'f':
163 free_table();
164 select_table_format(in);
165 break;
166 case 'h':
167 print_help();
168 break;
169 case 'n':
170 free_table();
171 table.new_table(in, &table.data);
172 break;
173 case 'p':
174 table.print_parts(&table.data);
175 break;
176 case 'q':
177 putchar('\n');
178 goto end;
179 case 'w':
180 table.write_parts(dev_handle, &table.data);
181 break;
182 default:
183 printf("Unknown command. Try 'h' for help.\n");
184 break;
185 }
186 }
187
188end:
189 tinput_destroy(in);
190
191 return EOK;
192}
193
194void print_help(void)
195{
196 printf(
197 "\t 'a' \t\t Add partition.\n"
198 "\t 'd' \t\t Delete partition.\n"
199 "\t 'e' \t\t Extra functions (per table format).\n"
200 "\t 'f' \t\t Switch the format of the partition table."
201 "\t 'h' \t\t Prints help. See help for more.\n"
202 "\t 'n' \t\t Create new table (discarding the old one).\n"
203 "\t 'p' \t\t Prints the table contents.\n"
204 "\t 'w' \t\t Write table to disk.\n"
205 "\t 'q' \t\t Quit.\n"
206 );
207
208}
209
210void select_table_format(tinput_t * in)
211{
212 printf("Available formats are: \n"
213 "1) MBR\n"
214 "2) GPT\n"
215 );
216
217 uint8_t val = get_input_uint8(in);
218 switch(val) {
219 case 0:
220 table.layout = LYT_NONE;
221 fill_table_funcs();
222 break;
223 case 1:
224 table.layout = LYT_MBR;
225 fill_table_funcs();
226 break;
227 case 2:
228 table.layout = LYT_GPT;
229 fill_table_funcs();
230 break;
231 }
232}
233
234void fill_table_funcs(void)
235{
236 switch(table.layout) {
237 case LYT_MBR:
238 table.add_part = add_mbr_part;
239 table.delete_part = delete_mbr_part;
240 table.new_table = new_mbr_table;
241 table.print_parts = print_mbr_parts;
242 table.write_parts = write_mbr_parts;
243 table.extra_funcs = extra_mbr_funcs;
244 break;
245 case LYT_GPT:
246 table.add_part = add_gpt_part;
247 table.delete_part = delete_gpt_part;
248 table.new_table = new_gpt_table;
249 table.print_parts = print_gpt_parts;
250 table.write_parts = write_gpt_parts;
251 table.extra_funcs = extra_gpt_funcs;
252 break;
253 default:
254 table.add_part = add_none_part;
255 table.delete_part = delete_none_part;
256 table.new_table = new_none_table;
257 table.print_parts = print_none_parts;
258 table.write_parts = write_none_parts;
259 table.extra_funcs = extra_none_funcs;
260 break;
261 }
262}
263
264void free_table(void)
265{
266 switch(table.layout) {
267 case LYT_MBR:
268 if (table.data.mbr.parts != NULL) {
269 mbr_free_partitions(table.data.mbr.parts);
270 table.data.mbr.parts = NULL;
271 }
272 if (table.data.mbr.mbr != NULL) {
273 mbr_free_mbr(table.data.mbr.mbr);
274 table.data.mbr.mbr = NULL;
275 }
276 break;
277 case LYT_GPT:
278 if (table.data.gpt.parts != NULL) {
279 gpt_free_partitions(table.data.gpt.parts);
280 table.data.gpt.parts = NULL;
281 }
282 if (table.data.gpt.gpt != NULL) {
283 gpt_free_gpt(table.data.gpt.gpt);
284 table.data.gpt.gpt = NULL;
285 }
286 break;
287 default:
288 break;
289 }
290}
291
292
293
Note: See TracBrowser for help on using the repository browser.