source: mainline/uspace/app/fdisk/fdisk.c@ 460ea7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 460ea7e was 460ea7e, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Fix use of uninitialized variable

  • Property mode set to 100644
File size: 24.9 KB
RevLine 
[e96047c]1/*
[64ffd83]2 * Copyright (c) 2018 Jiri Svoboda
[e96047c]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 fdisk
30 * @{
31 */
32/**
33 * @file
34 */
35
[6c4eedf]36#include <cap.h>
[e96047c]37#include <errno.h>
[db9c889]38#include <fdisk.h>
39#include <io/label.h>
[e96047c]40#include <nchoice.h>
41#include <stdbool.h>
42#include <stdio.h>
43#include <stdlib.h>
[1d6dd2a]44#include <str.h>
[db9c889]45#include <vol.h>
[e96047c]46
[9c2c7d2]47#define NO_LABEL_CAPTION "(No name)"
48
[e96047c]49static bool quit = false;
[22fb7ab]50static fdisk_t *fdisk;
[e96047c]51
52/** Device menu actions */
53typedef enum {
54 /** Create label */
55 devac_create_label,
56 /** Delete label */
57 devac_delete_label,
[ea0ff6b]58 /** Erase disk */
59 devac_erase_disk,
[b7a4d06]60 /** Create (primary) partition */
61 devac_create_pri_part,
62 /** Create extended partition */
63 devac_create_ext_part,
64 /** Create logical partition */
65 devac_create_log_part,
[2d78d88]66 /** Modify partition */
67 devac_modify_part,
[e96047c]68 /** Delete partition */
69 devac_delete_part,
70 /** Exit */
71 devac_exit
72} devac_t;
73
[2d78d88]74/** Partition property to modify */
75typedef enum {
76 /** Modify mount point */
77 pm_mountp,
78 /** Cancel */
79 pm_cancel
80} pmprop_t;
81
[ef9dac04]82/** Confirm user selection. */
[b7fd2a0]83static errno_t fdsk_confirm(const char *msg, bool *rconfirm)
[ef9dac04]84{
85 tinput_t *tinput = NULL;
86 char *answer;
[b7fd2a0]87 errno_t rc;
[ef9dac04]88
89 tinput = tinput_new();
90 if (tinput == NULL) {
91 rc = ENOMEM;
92 goto error;
93 }
94
95 rc = tinput_set_prompt(tinput, "y/n> ");
96 if (rc != EOK)
97 goto error;
98
99 while (true) {
100 printf("%s\n", msg);
101
102 rc = tinput_read(tinput, &answer);
103 if (rc == ENOENT) {
104 *rconfirm = false;
105 free(answer);
106 break;
107 }
108
109 if (rc != EOK)
110 goto error;
111
112 if (str_cmp(answer, "y") == 0) {
113 *rconfirm = true;
114 free(answer);
115 break;
116 } else if (str_cmp(answer, "n") == 0) {
117 *rconfirm = false;
118 free(answer);
119 break;
120 }
121 }
122
123 tinput_destroy(tinput);
124 return EOK;
125error:
126 if (tinput != NULL)
127 tinput_destroy(tinput);
128 return rc;
129}
130
[e96047c]131/** Device selection */
[b7fd2a0]132static errno_t fdsk_dev_sel_choice(service_id_t *rsvcid)
[e96047c]133{
134 fdisk_dev_list_t *devlist = NULL;
135 fdisk_dev_info_t *info;
136 nchoice_t *choice = NULL;
137 char *svcname = NULL;
[6c4eedf]138 cap_spec_t cap;
[8227d63]139 fdisk_dev_info_t *sdev;
[e96047c]140 char *scap = NULL;
141 char *dtext = NULL;
142 service_id_t svcid;
143 void *sel;
[8227d63]144 int ndevs;
[b7fd2a0]145 errno_t rc;
[e96047c]146
147 rc = nchoice_create(&choice);
148 if (rc != EOK) {
149 assert(rc == ENOMEM);
150 printf("Out of memory.\n");
151 goto error;
152 }
153
154 rc = nchoice_set_prompt(choice, "Select device");
155 if (rc != EOK) {
156 assert(rc == ENOMEM);
157 printf("Out of memory.\n");
158 goto error;
159 }
160
[22fb7ab]161 rc = fdisk_dev_list_get(fdisk, &devlist);
[e96047c]162 if (rc != EOK) {
163 printf("Error getting device list.\n");
164 goto error;
165 }
166
167 info = fdisk_dev_first(devlist);
[8227d63]168 ndevs = 0;
[e96047c]169 while (info != NULL) {
[8227d63]170 rc = fdisk_dev_info_get_svcname(info, &svcname);
[e96047c]171 if (rc != EOK) {
[4627314]172 fdisk_dev_info_get_svcid(info, &svcid);
173 printf("Error getting device service name "
174 "(service ID %zu).\n", svcid);
175 info = fdisk_dev_next(info);
176 continue;
[e96047c]177 }
178
[8227d63]179 rc = fdisk_dev_info_capacity(info, &cap);
[e96047c]180 if (rc != EOK) {
[4627314]181 printf("Error getting device capacity "
182 "(device %s).\n", svcname);
183 info = fdisk_dev_next(info);
184 continue;
[e96047c]185 }
186
[6c4eedf]187 cap_simplify(&cap);
[9854a8f]188
[6c4eedf]189 rc = cap_format(&cap, &scap);
[e96047c]190 if (rc != EOK) {
191 assert(rc == ENOMEM);
192 printf("Out of memory.\n");
193 goto error;
194 }
195
[d5c1051]196 int ret = asprintf(&dtext, "%s (%s)", svcname, scap);
197 if (ret < 0) {
[e96047c]198 rc = ENOMEM;
199 printf("Out of memory.\n");
200 goto error;
201 }
202
203 free(svcname);
204 svcname = NULL;
205 free(scap);
206 scap = NULL;
207
[68b5dd11]208 rc = nchoice_add(choice, dtext, info, 0);
[e96047c]209 if (rc != EOK) {
210 assert(rc == ENOMEM);
211 printf("Out of memory.\n");
212 goto error;
213 }
214
[4627314]215 ++ndevs;
216
[e96047c]217 free(dtext);
218 dtext = NULL;
219
220 info = fdisk_dev_next(info);
221 }
222
[8227d63]223 if (ndevs == 0) {
224 printf("No disk devices found.\n");
225 rc = ENOENT;
226 goto error;
227 }
228
[68b5dd11]229 rc = nchoice_add(choice, "Exit", NULL, 0);
[8227d63]230 if (rc != EOK) {
231 assert(rc == ENOMEM);
232 printf("Out of memory.\n");
233 goto error;
234 }
235
[e96047c]236 rc = nchoice_get(choice, &sel);
237 if (rc != EOK) {
238 printf("Error getting user selection.\n");
239 return rc;
240 }
241
[8227d63]242 sdev = (fdisk_dev_info_t *)sel;
243 if (sdev != NULL) {
244 fdisk_dev_info_get_svcid(sdev, &svcid);
245 } else {
246 svcid = 0;
247 }
[e96047c]248
[8227d63]249 fdisk_dev_list_free(devlist);
[e96047c]250
251 nchoice_destroy(choice);
252 *rsvcid = svcid;
253 return EOK;
254error:
[9b07fba]255 assert(rc != EOK);
256 *rsvcid = 0;
[e96047c]257 if (devlist != NULL)
258 fdisk_dev_list_free(devlist);
259 if (choice != NULL)
260 nchoice_destroy(choice);
261 free(dtext);
262 free(svcname);
263 free(scap);
264 return rc;
265}
266
[b7fd2a0]267static errno_t fdsk_create_label(fdisk_dev_t *dev)
[e96047c]268{
269 nchoice_t *choice = NULL;
270 void *sel;
[8227d63]271 char *sltype = NULL;
272 int i;
[b7fd2a0]273 errno_t rc;
[e96047c]274
275 rc = nchoice_create(&choice);
276 if (rc != EOK) {
277 assert(rc == ENOMEM);
278 printf("Out of memory.\n");
279 goto error;
280 }
281
282 rc = nchoice_set_prompt(choice, "Select label type");
283 if (rc != EOK) {
284 assert(rc == ENOMEM);
285 printf("Out of memory.\n");
286 goto error;
287 }
288
[372df8f]289 for (i = LT_FIRST; i < LT_LIMIT; i++) {
[db9c889]290 rc = label_type_format(i, &sltype);
[8227d63]291 if (rc != EOK)
292 goto error;
293
[68b5dd11]294 rc = nchoice_add(choice, sltype, (void *)(uintptr_t)i,
295 i == LT_DEFAULT);
[8227d63]296 if (rc != EOK) {
297 assert(rc == ENOMEM);
298 printf("Out of memory.\n");
299 goto error;
300 }
301
302 free(sltype);
303 sltype = NULL;
304 }
305
306 rc = nchoice_get(choice, &sel);
307 if (rc != EOK) {
308 printf("Error getting user selection.\n");
309 goto error;
310 }
311
[22fb7ab]312 rc = fdisk_label_create(dev, (label_type_t)sel);
[8227d63]313 if (rc != EOK) {
314 printf("Error creating label.\n");
315 goto error;
316 }
317
318 nchoice_destroy(choice);
319 return EOK;
320error:
321 free(sltype);
322 if (choice != NULL)
323 nchoice_destroy(choice);
324 return rc;
325}
326
[b7fd2a0]327static errno_t fdsk_delete_label(fdisk_dev_t *dev)
[8227d63]328{
[ef9dac04]329 bool confirm;
[b7fd2a0]330 errno_t rc;
[8227d63]331
[ef9dac04]332 rc = fdsk_confirm("Warning. Any data on disk will be lost. "
333 "Really delete label?", &confirm);
334 if (rc != EOK) {
335 printf("Error getting user confirmation.\n");
336 return rc;
337 }
338
339 if (!confirm)
340 return EOK;
341
[8227d63]342 rc = fdisk_label_destroy(dev);
343 if (rc != EOK) {
344 printf("Error deleting label.\n");
345 return rc;
346 }
347
348 return EOK;
349}
350
[b7fd2a0]351static errno_t fdsk_erase_disk(fdisk_dev_t *dev)
[ea0ff6b]352{
[ef9dac04]353 bool confirm;
[b7fd2a0]354 errno_t rc;
[ea0ff6b]355
[ef9dac04]356 rc = fdsk_confirm("Warning. Any data on disk will be lost. "
357 "Really erase disk?", &confirm);
358 if (rc != EOK) {
359 printf("Error getting user confirmation.\n");
360 return rc;
361 }
362
363 if (!confirm)
364 return EOK;
365
[ea0ff6b]366 rc = fdisk_dev_erase(dev);
367 if (rc != EOK) {
368 printf("Error erasing disk.\n");
369 return rc;
370 }
371
372 return EOK;
373}
374
[b7fd2a0]375static errno_t fdsk_select_fstype(vol_fstype_t *fstype)
[8227d63]376{
377 nchoice_t *choice = NULL;
378 void *sel;
[460ea7e]379 char *sfstype = NULL;
[8227d63]380 int i;
[b7fd2a0]381 errno_t rc;
[8227d63]382
383 rc = nchoice_create(&choice);
[e96047c]384 if (rc != EOK) {
385 assert(rc == ENOMEM);
386 printf("Out of memory.\n");
387 goto error;
388 }
389
[8227d63]390 rc = nchoice_set_prompt(choice, "Select file system type");
[e96047c]391 if (rc != EOK) {
392 assert(rc == ENOMEM);
393 printf("Out of memory.\n");
394 goto error;
395 }
396
[4b6635a7]397 for (i = 0; i < VOL_FSTYPE_LIMIT; i++) {
[db9c889]398 rc = vol_fstype_format(i, &sfstype);
[8227d63]399 if (rc != EOK)
400 goto error;
401
[68b5dd11]402 rc = nchoice_add(choice, sfstype, (void *)(uintptr_t)i,
403 i == VOL_FSTYPE_DEFAULT);
[8227d63]404 if (rc != EOK) {
405 assert(rc == ENOMEM);
406 printf("Out of memory.\n");
407 goto error;
408 }
409
410 free(sfstype);
411 sfstype = NULL;
412 }
413
[e96047c]414 rc = nchoice_get(choice, &sel);
415 if (rc != EOK) {
416 printf("Error getting user selection.\n");
417 goto error;
418 }
419
[8227d63]420 nchoice_destroy(choice);
[4b6635a7]421 *fstype = (vol_fstype_t)sel;
[8227d63]422 return EOK;
423error:
424 free(sfstype);
425 if (choice != NULL)
426 nchoice_destroy(choice);
427 return rc;
428}
429
[b7fd2a0]430static errno_t fdsk_create_part(fdisk_dev_t *dev, label_pkind_t pkind)
[8227d63]431{
[b7fd2a0]432 errno_t rc;
[8227d63]433 fdisk_part_spec_t pspec;
[6c4eedf]434 cap_spec_t cap;
435 cap_spec_t mcap;
[9c2c7d2]436 vol_label_supp_t vlsupp;
[4b6635a7]437 vol_fstype_t fstype = 0;
[8227d63]438 tinput_t *tinput = NULL;
[b598460a]439 fdisk_spc_t spc;
[8227d63]440 char *scap;
[b598460a]441 char *smcap = NULL;
[9c2c7d2]442 char *label = NULL;
[64ffd83]443 char *mountp = NULL;
[b598460a]444
445 if (pkind == lpk_logical)
446 spc = spc_log;
447 else
448 spc = spc_pri;
449
450 rc = fdisk_part_get_max_avail(dev, spc, &mcap);
451 if (rc != EOK) {
452 rc = EIO;
453 goto error;
454 }
455
[6c4eedf]456 cap_simplify(&mcap);
[03661d19]457
[6c4eedf]458 rc = cap_format(&mcap, &smcap);
[b598460a]459 if (rc != EOK) {
460 rc = ENOMEM;
461 goto error;
462 }
[8227d63]463
464 tinput = tinput_new();
465 if (tinput == NULL) {
466 rc = ENOMEM;
467 goto error;
468 }
469
470 rc = tinput_set_prompt(tinput, "?> ");
471 if (rc != EOK)
472 goto error;
473
474 while (true) {
475 printf("Enter capacity of new partition.\n");
[b598460a]476 rc = tinput_read_i(tinput, smcap, &scap);
[8227d63]477 if (rc != EOK)
478 goto error;
479
[6c4eedf]480 rc = cap_parse(scap, &cap);
[8227d63]481 if (rc == EOK)
482 break;
483 }
484
485 tinput_destroy(tinput);
[78d50bd]486 tinput = NULL;
[b598460a]487 free(smcap);
488 smcap = NULL;
[8227d63]489
[b7a4d06]490 if (pkind != lpk_extended) {
491 rc = fdsk_select_fstype(&fstype);
492 if (rc != EOK)
493 goto error;
494 }
[8227d63]495
[9c2c7d2]496 fdisk_get_vollabel_support(dev, fstype, &vlsupp);
497 if (vlsupp.supported) {
498 tinput = tinput_new();
499 if (tinput == NULL) {
500 rc = ENOMEM;
501 goto error;
502 }
503
504 rc = tinput_set_prompt(tinput, "?> ");
505 if (rc != EOK)
506 goto error;
507
508 /* Ask for volume label */
509 printf("Enter volume label for new partition.\n");
[f3504c1]510 rc = tinput_read_i(tinput, "New volume", &label);
[9c2c7d2]511 if (rc != EOK)
512 goto error;
513
[1433ecda]514 tinput_destroy(tinput);
[9c2c7d2]515 tinput = NULL;
516 }
517
[44428bb]518 /* Ask for mount point */
519 tinput = tinput_new();
520 if (tinput == NULL) {
521 rc = ENOMEM;
522 goto error;
523 }
524
525 rc = tinput_set_prompt(tinput, "?> ");
526 if (rc != EOK)
527 goto error;
528
529 while (true) {
530 printf("Enter mount point for new partition (Auto, None or /path).\n");
531 rc = tinput_read_i(tinput, "Auto", &mountp);
532 if (rc != EOK)
533 goto error;
534
535 rc = vol_mountp_validate(mountp);
536 if (rc == EOK)
537 break;
538
539 free(mountp);
540 mountp = NULL;
541 }
542
543 tinput_destroy(tinput);
544 tinput = NULL;
[64ffd83]545
[8227d63]546 fdisk_pspec_init(&pspec);
547 pspec.capacity = cap;
[b7a4d06]548 pspec.pkind = pkind;
[8227d63]549 pspec.fstype = fstype;
[9c2c7d2]550 pspec.label = label;
[64ffd83]551 pspec.mountp = mountp;
[8227d63]552
553 rc = fdisk_part_create(dev, &pspec, NULL);
[e96047c]554 if (rc != EOK) {
[8227d63]555 printf("Error creating partition.\n");
[e96047c]556 goto error;
557 }
558
[9c2c7d2]559 free(label);
[64ffd83]560 free(mountp);
[8227d63]561 return EOK;
562error:
[b598460a]563 free(smcap);
[9c2c7d2]564 free(label);
[64ffd83]565 free(mountp);
[8227d63]566 if (tinput != NULL)
567 tinput_destroy(tinput);
568 return rc;
569}
570
[2d78d88]571/** Add an option to choice for each partition.
572 *
573 * @param dev Fdisk device
574 * @param choice Choice to add optionts to
575 *
576 * @return EOK on sucess or error code
577 */
578static errno_t fdsk_add_part_choices(fdisk_dev_t *dev,
579 nchoice_t *choice)
[8227d63]580{
581 fdisk_part_t *part;
582 fdisk_part_info_t pinfo;
583 char *scap = NULL;
[21f1543]584 char *spkind = NULL;
[8227d63]585 char *sfstype = NULL;
586 char *sdesc = NULL;
[9c2c7d2]587 const char *label;
[b7fd2a0]588 errno_t rc;
[8227d63]589
590 part = fdisk_part_first(dev);
591 while (part != NULL) {
592 rc = fdisk_part_get_info(part, &pinfo);
593 if (rc != EOK) {
594 printf("Error getting partition information.\n");
595 goto error;
596 }
597
[6c4eedf]598 cap_simplify(&pinfo.capacity);
[9854a8f]599
[6c4eedf]600 rc = cap_format(&pinfo.capacity, &scap);
[8227d63]601 if (rc != EOK) {
602 printf("Out of memory.\n");
603 goto error;
604 }
605
[db9c889]606 rc = label_pkind_format(pinfo.pkind, &spkind);
[8227d63]607 if (rc != EOK) {
[21f1543]608 printf("\nOut of memory.\n");
[8227d63]609 goto error;
610 }
611
[21f1543]612 if (pinfo.pkind != lpk_extended) {
[db9c889]613 rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
[21f1543]614 if (rc != EOK) {
615 printf("Out of memory.\n");
616 goto error;
617 }
618
[9c2c7d2]619 if (str_size(pinfo.label) > 0)
620 label = pinfo.label;
621 else
622 label = "(No name)";
623
[d5c1051]624 int ret = asprintf(&sdesc, "%s %s, %s, %s", label,
[9c2c7d2]625 scap, spkind, sfstype);
[d5c1051]626 if (ret < 0) {
[21f1543]627 rc = ENOMEM;
628 goto error;
629 }
630
631 } else {
[d5c1051]632 int ret = asprintf(&sdesc, "%s, %s", scap, spkind);
633 if (ret < 0) {
[21f1543]634 rc = ENOMEM;
635 goto error;
636 }
[8227d63]637 }
638
[68b5dd11]639 rc = nchoice_add(choice, sdesc, (void *)part, 0);
[8227d63]640 if (rc != EOK) {
641 assert(rc == ENOMEM);
642 printf("Out of memory.\n");
643 goto error;
644 }
645
646 free(scap);
647 scap = NULL;
[21f1543]648 free(spkind);
649 spkind = NULL;
[8227d63]650 free(sfstype);
651 sfstype = NULL;
652 free(sdesc);
653 sdesc = NULL;
654
655 part = fdisk_part_next(part);
656 }
657
[2d78d88]658 return EOK;
659error:
660 free(scap);
661 free(spkind);
662 free(sfstype);
663 free(sdesc);
664
665 return rc;
666}
667
668/** Modify partition mount point.
669 *
670 * Run the interaction to modify a partition mount point
671 *
672 * @part Fdisk partition
673 * @return EOK on success or error code
674 */
675static errno_t fdsk_modify_mountp(fdisk_part_t *part)
676{
677 tinput_t *tinput = NULL;
678 errno_t rc;
679 char *mountp = NULL;
680
681 /* Ask for mount point */
682 tinput = tinput_new();
683 if (tinput == NULL) {
684 rc = ENOMEM;
685 goto error;
686 }
687
688 rc = tinput_set_prompt(tinput, "?> ");
689 if (rc != EOK)
690 goto error;
691
692 while (true) {
693 printf("Enter mount point for new partition (Auto, None or /path).\n");
694 rc = tinput_read_i(tinput, "Auto", &mountp);
695 if (rc != EOK)
696 goto error;
697
698 rc = vol_mountp_validate(mountp);
699 if (rc == EOK)
700 break;
701
702 free(mountp);
703 mountp = NULL;
704 }
705
706 rc = fdisk_part_set_mountp(part, mountp);
707 if (rc != EOK)
708 goto error;
709
710 free(mountp);
711
712 tinput_destroy(tinput);
713 tinput = NULL;
714 return EOK;
715error:
716 if (mountp != NULL)
717 free(mountp);
718 if (tinput != NULL)
719 tinput_destroy(tinput);
720 return rc;
721}
722
723/** Modify partition.
724 *
725 * Run the interaction to modify a partition.
726 *
727 * @param dev Fdisk device
728 * @return EOK on success or error code
729 */
730static errno_t fdsk_modify_part(fdisk_dev_t *dev)
731{
732 nchoice_t *choice = NULL;
733 fdisk_part_t *part;
734 void *sel;
735 errno_t rc;
736
737 rc = nchoice_create(&choice);
738 if (rc != EOK) {
739 assert(rc == ENOMEM);
740 printf("Out of memory.\n");
741 goto error;
742 }
743
744 rc = nchoice_set_prompt(choice, "Select partition to modify");
745 if (rc != EOK) {
746 assert(rc == ENOMEM);
747 printf("Out of memory.\n");
748 goto error;
749 }
750
751 rc = fdsk_add_part_choices(dev, choice);
752 if (rc != EOK)
753 goto error;
754
755 rc = nchoice_add(choice, "Cancel", NULL, 0);
756 if (rc != EOK) {
757 assert(rc == ENOMEM);
758 printf("Out of memory.\n");
759 goto error;
760 }
761
762 rc = nchoice_get(choice, &sel);
763 if (rc == ENOENT)
764 return EOK;
765 if (rc != EOK) {
766 printf("Error getting user selection.\n");
767 goto error;
768 }
769
770 nchoice_destroy(choice);
771 choice = NULL;
772
773 if (sel == NULL)
774 return EOK;
775
776 part = (fdisk_part_t *)sel;
777
778 rc = nchoice_create(&choice);
779 if (rc != EOK) {
780 assert(rc == ENOMEM);
781 printf("Out of memory.\n");
782 goto error;
783 }
784
785 rc = nchoice_set_prompt(choice, "Select property to modify");
786 if (rc != EOK) {
787 assert(rc == ENOMEM);
788 printf("Out of memory.\n");
789 goto error;
790 }
791
792 rc = nchoice_add(choice, "Mount point", (void *)pm_mountp, 0);
793 if (rc != EOK) {
794 assert(rc == ENOMEM);
795 printf("Out of memory.\n");
796 goto error;
797 }
798
799 rc = nchoice_add(choice, "Cancel", (void *)pm_cancel, 0);
800 if (rc != EOK) {
801 assert(rc == ENOMEM);
802 printf("Out of memory.\n");
803 goto error;
804 }
805
806 rc = nchoice_get(choice, &sel);
807 if (rc == ENOENT)
808 return EOK;
809 if (rc != EOK) {
810 printf("Error getting user selection.\n");
811 goto error;
812 }
813
814 nchoice_destroy(choice);
815 choice = NULL;
816
817 switch ((pmprop_t)sel) {
818 case pm_mountp:
819 rc = fdsk_modify_mountp(part);
820 break;
821 case pm_cancel:
822 rc = EOK;
823 break;
824 }
825
826 return rc;
827error:
828 if (choice != NULL)
829 nchoice_destroy(choice);
830 return rc;
831}
832
833static errno_t fdsk_delete_part(fdisk_dev_t *dev)
834{
835 nchoice_t *choice = NULL;
836 bool confirm;
837 void *sel;
838 errno_t rc;
839
840 rc = nchoice_create(&choice);
841 if (rc != EOK) {
842 assert(rc == ENOMEM);
843 printf("Out of memory.\n");
844 goto error;
845 }
846
847 rc = nchoice_set_prompt(choice, "Select partition to delete");
848 if (rc != EOK) {
849 assert(rc == ENOMEM);
850 printf("Out of memory.\n");
851 goto error;
852 }
853
854 rc = fdsk_add_part_choices(dev, choice);
855 if (rc != EOK)
856 goto error;
857
[21f1543]858 rc = nchoice_add(choice, "Cancel", NULL, 0);
859 if (rc != EOK) {
860 assert(rc == ENOMEM);
861 printf("Out of memory.\n");
862 goto error;
863 }
864
[8227d63]865 rc = nchoice_get(choice, &sel);
[ef9dac04]866 if (rc == ENOENT)
867 return EOK;
[8227d63]868 if (rc != EOK) {
869 printf("Error getting user selection.\n");
870 goto error;
871 }
872
[e96047c]873 nchoice_destroy(choice);
[ef9dac04]874 choice = NULL;
875
876 if (sel == NULL)
877 return EOK;
878
879 rc = fdsk_confirm("Warning. Any data in partition will be lost. "
880 "Really delete partition?", &confirm);
881 if (rc != EOK) {
882 printf("Error getting user confirmation.\n");
883 goto error;
884 }
885
886 if (!confirm)
887 return EOK;
888
889 rc = fdisk_part_destroy((fdisk_part_t *)sel);
890 if (rc != EOK) {
891 printf("Error deleting partition.\n");
892 return rc;
893 }
894
[e96047c]895 return EOK;
896error:
897 if (choice != NULL)
898 nchoice_destroy(choice);
899 return rc;
900}
901
902/** Device menu */
[b7fd2a0]903static errno_t fdsk_dev_menu(fdisk_dev_t *dev)
[e96047c]904{
905 nchoice_t *choice = NULL;
906 fdisk_label_info_t linfo;
[8227d63]907 fdisk_part_t *part;
908 fdisk_part_info_t pinfo;
[6c4eedf]909 cap_spec_t cap;
910 cap_spec_t mcap;
[ea0ff6b]911 fdisk_dev_flags_t dflags;
[e96047c]912 char *sltype = NULL;
[8227d63]913 char *sdcap = NULL;
914 char *scap = NULL;
[852664b9]915 char *smcap = NULL;
[8227d63]916 char *sfstype = NULL;
917 char *svcname = NULL;
[b7a4d06]918 char *spkind;
[d858a660]919 const char *label;
[b7fd2a0]920 errno_t rc;
[8227d63]921 int npart;
[e96047c]922 void *sel;
923
924 rc = nchoice_create(&choice);
925 if (rc != EOK) {
926 assert(rc == ENOMEM);
927 printf("Out of memory.\n");
928 goto error;
929 }
930
931 rc = nchoice_set_prompt(choice, "Select action");
932 if (rc != EOK) {
933 assert(rc == ENOMEM);
934 printf("Out of memory.\n");
935 goto error;
936 }
937
[8227d63]938 rc = fdisk_dev_capacity(dev, &cap);
939 if (rc != EOK) {
940 printf("Error getting device capacity.\n");
941 goto error;
942 }
943
[6c4eedf]944 cap_simplify(&cap);
[9854a8f]945
[6c4eedf]946 rc = cap_format(&cap, &sdcap);
[8227d63]947 if (rc != EOK) {
948 printf("Out of memory.\n");
949 goto error;
950 }
951
952 rc = fdisk_dev_get_svcname(dev, &svcname);
953 if (rc != EOK) {
954 printf("Error getting device service name.\n");
955 goto error;
956 }
957
[ea0ff6b]958 fdisk_dev_get_flags(dev, &dflags);
959
[d858a660]960 printf("Device: %s (%s)\n", svcname, sdcap);
[22fb7ab]961 free(sdcap);
962 sdcap = NULL;
963
[e96047c]964 rc = fdisk_label_get_info(dev, &linfo);
965 if (rc != EOK) {
966 printf("Error getting label information.\n");
967 goto error;
968 }
969
[0ecfc62]970 switch (linfo.ltype) {
971 case lt_none:
972 printf("Disk contains no label.\n");
[22fb7ab]973 break;
[0ecfc62]974 default:
[db9c889]975 rc = label_type_format(linfo.ltype, &sltype);
[22fb7ab]976 if (rc != EOK) {
977 assert(rc == ENOMEM);
978 printf("Out of memory.\n");
979 goto error;
980 }
[e96047c]981
[22fb7ab]982 printf("Label type: %s\n", sltype);
983 free(sltype);
984 sltype = NULL;
985 break;
986 }
[8227d63]987
988 part = fdisk_part_first(dev);
989 npart = 0;
990 while (part != NULL) {
991 ++npart;
992 rc = fdisk_part_get_info(part, &pinfo);
993 if (rc != EOK) {
994 printf("Error getting partition information.\n");
995 goto error;
996 }
997
[6c4eedf]998 cap_simplify(&pinfo.capacity);
[9854a8f]999
[6c4eedf]1000 rc = cap_format(&pinfo.capacity, &scap);
[8227d63]1001 if (rc != EOK) {
1002 printf("Out of memory.\n");
1003 goto error;
1004 }
1005
[db9c889]1006 rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
[8227d63]1007 if (rc != EOK) {
1008 printf("Out of memory.\n");
1009 goto error;
1010 }
1011
[d858a660]1012 if (str_size(pinfo.label) > 0)
1013 label = pinfo.label;
1014 else
[9c2c7d2]1015 label = "(No name)";
[d858a660]1016
[edebb4a1]1017 if (linfo.ltype == lt_none)
[d858a660]1018 printf("Entire disk: %s %s", label, scap);
[edebb4a1]1019 else
[d858a660]1020 printf("Partition %d: %s %s", npart, label, scap);
[edebb4a1]1021
[b7a4d06]1022 if ((linfo.flags & lf_ext_supp) != 0) {
[db9c889]1023 rc = label_pkind_format(pinfo.pkind, &spkind);
[b7a4d06]1024 if (rc != EOK) {
1025 printf("\nOut of memory.\n");
1026 goto error;
1027 }
1028
1029 printf(", %s", spkind);
1030 free(spkind);
1031 }
1032
[4b6635a7]1033 if (pinfo.pkind != lpk_extended) {
[2dab624]1034 printf(", %s", sfstype);
[4b6635a7]1035 }
1036
[b7a4d06]1037 printf("\n");
1038
[8227d63]1039 free(scap);
1040 scap = NULL;
1041 free(sfstype);
1042 sfstype = NULL;
1043
1044 part = fdisk_part_next(part);
1045 }
[e96047c]1046
[852664b9]1047 /* Display available space */
1048 if ((linfo.flags & lf_can_create_pri) != 0) {
1049 rc = fdisk_part_get_max_avail(dev, spc_pri, &mcap);
1050 if (rc != EOK) {
1051 rc = EIO;
1052 goto error;
1053 }
1054
[6c4eedf]1055 cap_simplify(&mcap);
[9854a8f]1056
[6c4eedf]1057 rc = cap_format(&mcap, &smcap);
[852664b9]1058 if (rc != EOK) {
1059 rc = ENOMEM;
1060 goto error;
1061 }
1062
1063 if ((linfo.flags & lf_ext_supp) != 0)
1064 printf("Maximum free primary block: %s\n", smcap);
1065 else
1066 printf("Maximum free block: %s\n", smcap);
1067
1068 free(smcap);
1069 smcap = NULL;
1070
1071 rc = fdisk_part_get_tot_avail(dev, spc_pri, &mcap);
1072 if (rc != EOK) {
1073 rc = EIO;
1074 goto error;
1075 }
1076
[6c4eedf]1077 cap_simplify(&mcap);
[9854a8f]1078
[6c4eedf]1079 rc = cap_format(&mcap, &smcap);
[852664b9]1080 if (rc != EOK) {
1081 rc = ENOMEM;
1082 goto error;
1083 }
1084
1085 if ((linfo.flags & lf_ext_supp) != 0)
1086 printf("Total free primary space: %s\n", smcap);
1087 else
1088 printf("Total free space: %s\n", smcap);
1089
1090 free(smcap);
1091 smcap = NULL;
1092 }
1093
1094 /* Display available space */
1095 if ((linfo.flags & lf_can_create_log) != 0) {
1096 rc = fdisk_part_get_max_avail(dev, spc_log, &mcap);
1097 if (rc != EOK) {
1098 rc = EIO;
1099 goto error;
1100 }
1101
[6c4eedf]1102 cap_simplify(&mcap);
[9854a8f]1103
[6c4eedf]1104 rc = cap_format(&mcap, &smcap);
[852664b9]1105 if (rc != EOK) {
1106 rc = ENOMEM;
1107 goto error;
1108 }
1109
1110 printf("Maximum free logical block: %s\n", smcap);
1111 free(smcap);
1112 smcap = NULL;
1113
1114 rc = fdisk_part_get_tot_avail(dev, spc_log, &mcap);
1115 if (rc != EOK) {
1116 rc = EIO;
1117 goto error;
1118 }
1119
[6c4eedf]1120 cap_simplify(&mcap);
[9854a8f]1121
[6c4eedf]1122 rc = cap_format(&mcap, &smcap);
[852664b9]1123 if (rc != EOK) {
1124 rc = ENOMEM;
1125 goto error;
1126 }
1127
1128 printf("Total free logical space: %s\n", smcap);
1129 free(smcap);
1130 smcap = NULL;
1131 }
1132
[e96047c]1133 rc = nchoice_set_prompt(choice, "Select action");
1134 if (rc != EOK) {
1135 assert(rc == ENOMEM);
1136 printf("Out of memory.\n");
1137 goto error;
1138 }
1139
[0ecfc62]1140 if ((linfo.flags & lf_ext_supp) != 0) {
1141 if ((linfo.flags & lf_can_create_pri) != 0) {
1142 rc = nchoice_add(choice, "Create primary "
1143 "partition",
[68b5dd11]1144 (void *)devac_create_pri_part, 0);
[0ecfc62]1145 if (rc != EOK) {
1146 assert(rc == ENOMEM);
1147 printf("Out of memory.\n");
1148 goto error;
[b7a4d06]1149 }
[0ecfc62]1150 }
[b7a4d06]1151
[0ecfc62]1152 if ((linfo.flags & lf_can_create_ext) != 0) {
1153 rc = nchoice_add(choice, "Create extended "
1154 "partition",
[68b5dd11]1155 (void *)devac_create_ext_part, 0);
[0ecfc62]1156 if (rc != EOK) {
1157 assert(rc == ENOMEM);
1158 printf("Out of memory.\n");
1159 goto error;
[b7a4d06]1160 }
[0ecfc62]1161 }
[b7a4d06]1162
[0ecfc62]1163 if ((linfo.flags & lf_can_create_log) != 0) {
1164 rc = nchoice_add(choice, "Create logical "
1165 "partition",
[68b5dd11]1166 (void *)devac_create_log_part, 0);
[0ecfc62]1167 if (rc != EOK) {
1168 assert(rc == ENOMEM);
1169 printf("Out of memory.\n");
1170 goto error;
[b7a4d06]1171 }
[0ecfc62]1172 }
1173 } else { /* (linfo.flags & lf_ext_supp) == 0 */
1174 if ((linfo.flags & lf_can_create_pri) != 0) {
1175 rc = nchoice_add(choice, "Create partition",
[68b5dd11]1176 (void *)devac_create_pri_part, 0);
[0ecfc62]1177 if (rc != EOK) {
1178 assert(rc == ENOMEM);
[1433ecda]1179 printf("Out of memory.\n");
1180 goto error;
1181 }
[8227d63]1182 }
1183 }
1184
[2d78d88]1185 if ((linfo.flags & lf_can_modify_part) != 0) {
1186 rc = nchoice_add(choice, "Modify partition",
1187 (void *)devac_modify_part, 0);
1188 if (rc != EOK) {
1189 assert(rc == ENOMEM);
1190 printf("Out of memory.\n");
1191 goto error;
1192 }
1193 }
1194
[edebb4a1]1195 if ((linfo.flags & lf_can_delete_part) != 0) {
[8227d63]1196 rc = nchoice_add(choice, "Delete partition",
[68b5dd11]1197 (void *)devac_delete_part, 0);
[8227d63]1198 if (rc != EOK) {
1199 assert(rc == ENOMEM);
1200 printf("Out of memory.\n");
1201 goto error;
1202 }
1203 }
1204
[ea0ff6b]1205 if ((dflags & fdf_can_create_label) != 0) {
[e96047c]1206 rc = nchoice_add(choice, "Create label",
[68b5dd11]1207 (void *)devac_create_label, 0);
[e96047c]1208 if (rc != EOK) {
1209 assert(rc == ENOMEM);
1210 printf("Out of memory.\n");
1211 goto error;
1212 }
[ea0ff6b]1213 }
1214
1215 if ((dflags & fdf_can_delete_label) != 0) {
[e96047c]1216 rc = nchoice_add(choice, "Delete label",
[68b5dd11]1217 (void *)devac_delete_label, 0);
[e96047c]1218 if (rc != EOK) {
1219 assert(rc == ENOMEM);
1220 printf("Out of memory.\n");
1221 goto error;
1222 }
1223 }
1224
[ea0ff6b]1225 if ((dflags & fdf_can_erase_dev) != 0) {
1226 rc = nchoice_add(choice, "Erase disk",
[68b5dd11]1227 (void *)devac_erase_disk, 0);
[ea0ff6b]1228 if (rc != EOK) {
1229 assert(rc == ENOMEM);
1230 printf("Out of memory.\n");
1231 goto error;
1232 }
1233 }
1234
[68b5dd11]1235 rc = nchoice_add(choice, "Exit", (void *)devac_exit, 0);
[e96047c]1236 if (rc != EOK) {
1237 assert(rc == ENOMEM);
1238 printf("Out of memory.\n");
1239 goto error;
1240 }
1241
1242 rc = nchoice_get(choice, &sel);
1243 if (rc != EOK) {
1244 printf("Error getting user selection.\n");
1245 return rc;
1246 }
1247
1248 switch ((devac_t)sel) {
1249 case devac_create_label:
[22fb7ab]1250 (void) fdsk_create_label(dev);
[e96047c]1251 break;
1252 case devac_delete_label:
[22fb7ab]1253 (void) fdsk_delete_label(dev);
[e96047c]1254 break;
[ea0ff6b]1255 case devac_erase_disk:
1256 (void) fdsk_erase_disk(dev);
1257 break;
[b7a4d06]1258 case devac_create_pri_part:
1259 (void) fdsk_create_part(dev, lpk_primary);
1260 break;
1261 case devac_create_ext_part:
1262 (void) fdsk_create_part(dev, lpk_extended);
1263 break;
1264 case devac_create_log_part:
1265 (void) fdsk_create_part(dev, lpk_logical);
[e96047c]1266 break;
[2d78d88]1267 case devac_modify_part:
1268 (void) fdsk_modify_part(dev);
1269 break;
[e96047c]1270 case devac_delete_part:
[22fb7ab]1271 (void) fdsk_delete_part(dev);
[e96047c]1272 break;
1273 case devac_exit:
1274 quit = true;
1275 break;
1276 }
1277
1278 nchoice_destroy(choice);
1279 return EOK;
1280error:
[8227d63]1281 free(sdcap);
1282 free(scap);
[852664b9]1283 free(smcap);
[8227d63]1284 free(sfstype);
1285 free(svcname);
[e96047c]1286 if (choice != NULL)
1287 nchoice_destroy(choice);
1288 return rc;
1289}
1290
1291int main(int argc, char *argv[])
1292{
1293 service_id_t svcid;
1294 fdisk_dev_t *dev;
[b7fd2a0]1295 errno_t rc;
[e96047c]1296
[22fb7ab]1297 rc = fdisk_create(&fdisk);
1298 if (rc != EOK) {
1299 printf("Error initializing Fdisk.\n");
1300 return 1;
1301 }
1302
[e96047c]1303 rc = fdsk_dev_sel_choice(&svcid);
1304 if (rc != EOK)
1305 return 1;
1306
[8227d63]1307 if (svcid == 0)
1308 return 0;
1309
[22fb7ab]1310 rc = fdisk_dev_open(fdisk, svcid, &dev);
[e96047c]1311 if (rc != EOK) {
1312 printf("Error opening device.\n");
1313 return 1;
1314 }
1315
1316 while (!quit) {
1317 rc = fdsk_dev_menu(dev);
1318 if (rc != EOK) {
1319 fdisk_dev_close(dev);
1320 return 1;
1321 }
1322 }
1323
1324 fdisk_dev_close(dev);
[22fb7ab]1325 fdisk_destroy(fdisk);
[e96047c]1326
1327 return 0;
1328}
1329
1330/** @}
1331 */
Note: See TracBrowser for help on using the repository browser.