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
Line 
1/*
2 * Copyright (c) 2018 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 * @{
31 */
32/**
33 * @file
34 */
35
36#include <cap.h>
37#include <errno.h>
38#include <fdisk.h>
39#include <io/label.h>
40#include <nchoice.h>
41#include <stdbool.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <str.h>
45#include <vol.h>
46
47#define NO_LABEL_CAPTION "(No name)"
48
49static bool quit = false;
50static fdisk_t *fdisk;
51
52/** Device menu actions */
53typedef enum {
54 /** Create label */
55 devac_create_label,
56 /** Delete label */
57 devac_delete_label,
58 /** Erase disk */
59 devac_erase_disk,
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,
66 /** Modify partition */
67 devac_modify_part,
68 /** Delete partition */
69 devac_delete_part,
70 /** Exit */
71 devac_exit
72} devac_t;
73
74/** Partition property to modify */
75typedef enum {
76 /** Modify mount point */
77 pm_mountp,
78 /** Cancel */
79 pm_cancel
80} pmprop_t;
81
82/** Confirm user selection. */
83static errno_t fdsk_confirm(const char *msg, bool *rconfirm)
84{
85 tinput_t *tinput = NULL;
86 char *answer;
87 errno_t rc;
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
131/** Device selection */
132static errno_t fdsk_dev_sel_choice(service_id_t *rsvcid)
133{
134 fdisk_dev_list_t *devlist = NULL;
135 fdisk_dev_info_t *info;
136 nchoice_t *choice = NULL;
137 char *svcname = NULL;
138 cap_spec_t cap;
139 fdisk_dev_info_t *sdev;
140 char *scap = NULL;
141 char *dtext = NULL;
142 service_id_t svcid;
143 void *sel;
144 int ndevs;
145 errno_t rc;
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
161 rc = fdisk_dev_list_get(fdisk, &devlist);
162 if (rc != EOK) {
163 printf("Error getting device list.\n");
164 goto error;
165 }
166
167 info = fdisk_dev_first(devlist);
168 ndevs = 0;
169 while (info != NULL) {
170 rc = fdisk_dev_info_get_svcname(info, &svcname);
171 if (rc != EOK) {
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;
177 }
178
179 rc = fdisk_dev_info_capacity(info, &cap);
180 if (rc != EOK) {
181 printf("Error getting device capacity "
182 "(device %s).\n", svcname);
183 info = fdisk_dev_next(info);
184 continue;
185 }
186
187 cap_simplify(&cap);
188
189 rc = cap_format(&cap, &scap);
190 if (rc != EOK) {
191 assert(rc == ENOMEM);
192 printf("Out of memory.\n");
193 goto error;
194 }
195
196 int ret = asprintf(&dtext, "%s (%s)", svcname, scap);
197 if (ret < 0) {
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
208 rc = nchoice_add(choice, dtext, info, 0);
209 if (rc != EOK) {
210 assert(rc == ENOMEM);
211 printf("Out of memory.\n");
212 goto error;
213 }
214
215 ++ndevs;
216
217 free(dtext);
218 dtext = NULL;
219
220 info = fdisk_dev_next(info);
221 }
222
223 if (ndevs == 0) {
224 printf("No disk devices found.\n");
225 rc = ENOENT;
226 goto error;
227 }
228
229 rc = nchoice_add(choice, "Exit", NULL, 0);
230 if (rc != EOK) {
231 assert(rc == ENOMEM);
232 printf("Out of memory.\n");
233 goto error;
234 }
235
236 rc = nchoice_get(choice, &sel);
237 if (rc != EOK) {
238 printf("Error getting user selection.\n");
239 return rc;
240 }
241
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 }
248
249 fdisk_dev_list_free(devlist);
250
251 nchoice_destroy(choice);
252 *rsvcid = svcid;
253 return EOK;
254error:
255 assert(rc != EOK);
256 *rsvcid = 0;
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
267static errno_t fdsk_create_label(fdisk_dev_t *dev)
268{
269 nchoice_t *choice = NULL;
270 void *sel;
271 char *sltype = NULL;
272 int i;
273 errno_t rc;
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
289 for (i = LT_FIRST; i < LT_LIMIT; i++) {
290 rc = label_type_format(i, &sltype);
291 if (rc != EOK)
292 goto error;
293
294 rc = nchoice_add(choice, sltype, (void *)(uintptr_t)i,
295 i == LT_DEFAULT);
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
312 rc = fdisk_label_create(dev, (label_type_t)sel);
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
327static errno_t fdsk_delete_label(fdisk_dev_t *dev)
328{
329 bool confirm;
330 errno_t rc;
331
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
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
351static errno_t fdsk_erase_disk(fdisk_dev_t *dev)
352{
353 bool confirm;
354 errno_t rc;
355
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
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
375static errno_t fdsk_select_fstype(vol_fstype_t *fstype)
376{
377 nchoice_t *choice = NULL;
378 void *sel;
379 char *sfstype = NULL;
380 int i;
381 errno_t rc;
382
383 rc = nchoice_create(&choice);
384 if (rc != EOK) {
385 assert(rc == ENOMEM);
386 printf("Out of memory.\n");
387 goto error;
388 }
389
390 rc = nchoice_set_prompt(choice, "Select file system type");
391 if (rc != EOK) {
392 assert(rc == ENOMEM);
393 printf("Out of memory.\n");
394 goto error;
395 }
396
397 for (i = 0; i < VOL_FSTYPE_LIMIT; i++) {
398 rc = vol_fstype_format(i, &sfstype);
399 if (rc != EOK)
400 goto error;
401
402 rc = nchoice_add(choice, sfstype, (void *)(uintptr_t)i,
403 i == VOL_FSTYPE_DEFAULT);
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
414 rc = nchoice_get(choice, &sel);
415 if (rc != EOK) {
416 printf("Error getting user selection.\n");
417 goto error;
418 }
419
420 nchoice_destroy(choice);
421 *fstype = (vol_fstype_t)sel;
422 return EOK;
423error:
424 free(sfstype);
425 if (choice != NULL)
426 nchoice_destroy(choice);
427 return rc;
428}
429
430static errno_t fdsk_create_part(fdisk_dev_t *dev, label_pkind_t pkind)
431{
432 errno_t rc;
433 fdisk_part_spec_t pspec;
434 cap_spec_t cap;
435 cap_spec_t mcap;
436 vol_label_supp_t vlsupp;
437 vol_fstype_t fstype = 0;
438 tinput_t *tinput = NULL;
439 fdisk_spc_t spc;
440 char *scap;
441 char *smcap = NULL;
442 char *label = NULL;
443 char *mountp = NULL;
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
456 cap_simplify(&mcap);
457
458 rc = cap_format(&mcap, &smcap);
459 if (rc != EOK) {
460 rc = ENOMEM;
461 goto error;
462 }
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");
476 rc = tinput_read_i(tinput, smcap, &scap);
477 if (rc != EOK)
478 goto error;
479
480 rc = cap_parse(scap, &cap);
481 if (rc == EOK)
482 break;
483 }
484
485 tinput_destroy(tinput);
486 tinput = NULL;
487 free(smcap);
488 smcap = NULL;
489
490 if (pkind != lpk_extended) {
491 rc = fdsk_select_fstype(&fstype);
492 if (rc != EOK)
493 goto error;
494 }
495
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");
510 rc = tinput_read_i(tinput, "New volume", &label);
511 if (rc != EOK)
512 goto error;
513
514 tinput_destroy(tinput);
515 tinput = NULL;
516 }
517
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;
545
546 fdisk_pspec_init(&pspec);
547 pspec.capacity = cap;
548 pspec.pkind = pkind;
549 pspec.fstype = fstype;
550 pspec.label = label;
551 pspec.mountp = mountp;
552
553 rc = fdisk_part_create(dev, &pspec, NULL);
554 if (rc != EOK) {
555 printf("Error creating partition.\n");
556 goto error;
557 }
558
559 free(label);
560 free(mountp);
561 return EOK;
562error:
563 free(smcap);
564 free(label);
565 free(mountp);
566 if (tinput != NULL)
567 tinput_destroy(tinput);
568 return rc;
569}
570
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)
580{
581 fdisk_part_t *part;
582 fdisk_part_info_t pinfo;
583 char *scap = NULL;
584 char *spkind = NULL;
585 char *sfstype = NULL;
586 char *sdesc = NULL;
587 const char *label;
588 errno_t rc;
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
598 cap_simplify(&pinfo.capacity);
599
600 rc = cap_format(&pinfo.capacity, &scap);
601 if (rc != EOK) {
602 printf("Out of memory.\n");
603 goto error;
604 }
605
606 rc = label_pkind_format(pinfo.pkind, &spkind);
607 if (rc != EOK) {
608 printf("\nOut of memory.\n");
609 goto error;
610 }
611
612 if (pinfo.pkind != lpk_extended) {
613 rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
614 if (rc != EOK) {
615 printf("Out of memory.\n");
616 goto error;
617 }
618
619 if (str_size(pinfo.label) > 0)
620 label = pinfo.label;
621 else
622 label = "(No name)";
623
624 int ret = asprintf(&sdesc, "%s %s, %s, %s", label,
625 scap, spkind, sfstype);
626 if (ret < 0) {
627 rc = ENOMEM;
628 goto error;
629 }
630
631 } else {
632 int ret = asprintf(&sdesc, "%s, %s", scap, spkind);
633 if (ret < 0) {
634 rc = ENOMEM;
635 goto error;
636 }
637 }
638
639 rc = nchoice_add(choice, sdesc, (void *)part, 0);
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;
648 free(spkind);
649 spkind = NULL;
650 free(sfstype);
651 sfstype = NULL;
652 free(sdesc);
653 sdesc = NULL;
654
655 part = fdisk_part_next(part);
656 }
657
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
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
865 rc = nchoice_get(choice, &sel);
866 if (rc == ENOENT)
867 return EOK;
868 if (rc != EOK) {
869 printf("Error getting user selection.\n");
870 goto error;
871 }
872
873 nchoice_destroy(choice);
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
895 return EOK;
896error:
897 if (choice != NULL)
898 nchoice_destroy(choice);
899 return rc;
900}
901
902/** Device menu */
903static errno_t fdsk_dev_menu(fdisk_dev_t *dev)
904{
905 nchoice_t *choice = NULL;
906 fdisk_label_info_t linfo;
907 fdisk_part_t *part;
908 fdisk_part_info_t pinfo;
909 cap_spec_t cap;
910 cap_spec_t mcap;
911 fdisk_dev_flags_t dflags;
912 char *sltype = NULL;
913 char *sdcap = NULL;
914 char *scap = NULL;
915 char *smcap = NULL;
916 char *sfstype = NULL;
917 char *svcname = NULL;
918 char *spkind;
919 const char *label;
920 errno_t rc;
921 int npart;
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
938 rc = fdisk_dev_capacity(dev, &cap);
939 if (rc != EOK) {
940 printf("Error getting device capacity.\n");
941 goto error;
942 }
943
944 cap_simplify(&cap);
945
946 rc = cap_format(&cap, &sdcap);
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
958 fdisk_dev_get_flags(dev, &dflags);
959
960 printf("Device: %s (%s)\n", svcname, sdcap);
961 free(sdcap);
962 sdcap = NULL;
963
964 rc = fdisk_label_get_info(dev, &linfo);
965 if (rc != EOK) {
966 printf("Error getting label information.\n");
967 goto error;
968 }
969
970 switch (linfo.ltype) {
971 case lt_none:
972 printf("Disk contains no label.\n");
973 break;
974 default:
975 rc = label_type_format(linfo.ltype, &sltype);
976 if (rc != EOK) {
977 assert(rc == ENOMEM);
978 printf("Out of memory.\n");
979 goto error;
980 }
981
982 printf("Label type: %s\n", sltype);
983 free(sltype);
984 sltype = NULL;
985 break;
986 }
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
998 cap_simplify(&pinfo.capacity);
999
1000 rc = cap_format(&pinfo.capacity, &scap);
1001 if (rc != EOK) {
1002 printf("Out of memory.\n");
1003 goto error;
1004 }
1005
1006 rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
1007 if (rc != EOK) {
1008 printf("Out of memory.\n");
1009 goto error;
1010 }
1011
1012 if (str_size(pinfo.label) > 0)
1013 label = pinfo.label;
1014 else
1015 label = "(No name)";
1016
1017 if (linfo.ltype == lt_none)
1018 printf("Entire disk: %s %s", label, scap);
1019 else
1020 printf("Partition %d: %s %s", npart, label, scap);
1021
1022 if ((linfo.flags & lf_ext_supp) != 0) {
1023 rc = label_pkind_format(pinfo.pkind, &spkind);
1024 if (rc != EOK) {
1025 printf("\nOut of memory.\n");
1026 goto error;
1027 }
1028
1029 printf(", %s", spkind);
1030 free(spkind);
1031 }
1032
1033 if (pinfo.pkind != lpk_extended) {
1034 printf(", %s", sfstype);
1035 }
1036
1037 printf("\n");
1038
1039 free(scap);
1040 scap = NULL;
1041 free(sfstype);
1042 sfstype = NULL;
1043
1044 part = fdisk_part_next(part);
1045 }
1046
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
1055 cap_simplify(&mcap);
1056
1057 rc = cap_format(&mcap, &smcap);
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
1077 cap_simplify(&mcap);
1078
1079 rc = cap_format(&mcap, &smcap);
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
1102 cap_simplify(&mcap);
1103
1104 rc = cap_format(&mcap, &smcap);
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
1120 cap_simplify(&mcap);
1121
1122 rc = cap_format(&mcap, &smcap);
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
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
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",
1144 (void *)devac_create_pri_part, 0);
1145 if (rc != EOK) {
1146 assert(rc == ENOMEM);
1147 printf("Out of memory.\n");
1148 goto error;
1149 }
1150 }
1151
1152 if ((linfo.flags & lf_can_create_ext) != 0) {
1153 rc = nchoice_add(choice, "Create extended "
1154 "partition",
1155 (void *)devac_create_ext_part, 0);
1156 if (rc != EOK) {
1157 assert(rc == ENOMEM);
1158 printf("Out of memory.\n");
1159 goto error;
1160 }
1161 }
1162
1163 if ((linfo.flags & lf_can_create_log) != 0) {
1164 rc = nchoice_add(choice, "Create logical "
1165 "partition",
1166 (void *)devac_create_log_part, 0);
1167 if (rc != EOK) {
1168 assert(rc == ENOMEM);
1169 printf("Out of memory.\n");
1170 goto error;
1171 }
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",
1176 (void *)devac_create_pri_part, 0);
1177 if (rc != EOK) {
1178 assert(rc == ENOMEM);
1179 printf("Out of memory.\n");
1180 goto error;
1181 }
1182 }
1183 }
1184
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
1195 if ((linfo.flags & lf_can_delete_part) != 0) {
1196 rc = nchoice_add(choice, "Delete partition",
1197 (void *)devac_delete_part, 0);
1198 if (rc != EOK) {
1199 assert(rc == ENOMEM);
1200 printf("Out of memory.\n");
1201 goto error;
1202 }
1203 }
1204
1205 if ((dflags & fdf_can_create_label) != 0) {
1206 rc = nchoice_add(choice, "Create label",
1207 (void *)devac_create_label, 0);
1208 if (rc != EOK) {
1209 assert(rc == ENOMEM);
1210 printf("Out of memory.\n");
1211 goto error;
1212 }
1213 }
1214
1215 if ((dflags & fdf_can_delete_label) != 0) {
1216 rc = nchoice_add(choice, "Delete label",
1217 (void *)devac_delete_label, 0);
1218 if (rc != EOK) {
1219 assert(rc == ENOMEM);
1220 printf("Out of memory.\n");
1221 goto error;
1222 }
1223 }
1224
1225 if ((dflags & fdf_can_erase_dev) != 0) {
1226 rc = nchoice_add(choice, "Erase disk",
1227 (void *)devac_erase_disk, 0);
1228 if (rc != EOK) {
1229 assert(rc == ENOMEM);
1230 printf("Out of memory.\n");
1231 goto error;
1232 }
1233 }
1234
1235 rc = nchoice_add(choice, "Exit", (void *)devac_exit, 0);
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:
1250 (void) fdsk_create_label(dev);
1251 break;
1252 case devac_delete_label:
1253 (void) fdsk_delete_label(dev);
1254 break;
1255 case devac_erase_disk:
1256 (void) fdsk_erase_disk(dev);
1257 break;
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);
1266 break;
1267 case devac_modify_part:
1268 (void) fdsk_modify_part(dev);
1269 break;
1270 case devac_delete_part:
1271 (void) fdsk_delete_part(dev);
1272 break;
1273 case devac_exit:
1274 quit = true;
1275 break;
1276 }
1277
1278 nchoice_destroy(choice);
1279 return EOK;
1280error:
1281 free(sdcap);
1282 free(scap);
1283 free(smcap);
1284 free(sfstype);
1285 free(svcname);
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;
1295 errno_t rc;
1296
1297 rc = fdisk_create(&fdisk);
1298 if (rc != EOK) {
1299 printf("Error initializing Fdisk.\n");
1300 return 1;
1301 }
1302
1303 rc = fdsk_dev_sel_choice(&svcid);
1304 if (rc != EOK)
1305 return 1;
1306
1307 if (svcid == 0)
1308 return 0;
1309
1310 rc = fdisk_dev_open(fdisk, svcid, &dev);
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);
1325 fdisk_destroy(fdisk);
1326
1327 return 0;
1328}
1329
1330/** @}
1331 */
Note: See TracBrowser for help on using the repository browser.