source: mainline/uspace/app/fdisk/fdisk.c@ ccf7a7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ccf7a7e was db9c889, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Add volume administration utility.

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