source: mainline/uspace/app/fdisk/fdisk.c@ 4d6629f

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

ExFAT volume label support.

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