source: mainline/uspace/app/fdisk/fdisk.c@ 508b0df1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 508b0df1 was a63966d, checked in by Jakub Jermar <jakub@…>, 7 years ago

Provide doc/doxygroups.h for most apps

  • 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;
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
874 nchoice_destroy(choice);
875 choice = NULL;
876
877 if (sel == NULL)
878 return EOK;
879
880 rc = fdsk_confirm("Warning. Any data in partition will be lost. "
881 "Really delete partition?", &confirm);
882 if (rc != EOK) {
883 printf("Error getting user confirmation.\n");
884 goto error;
885 }
886
887 if (!confirm)
888 return EOK;
889
890 rc = fdisk_part_destroy((fdisk_part_t *)sel);
891 if (rc != EOK) {
892 printf("Error deleting partition.\n");
893 return rc;
894 }
895
896 return EOK;
897error:
898 if (choice != NULL)
899 nchoice_destroy(choice);
900 return rc;
901}
902
903/** Device menu */
904static errno_t fdsk_dev_menu(fdisk_dev_t *dev)
905{
906 nchoice_t *choice = NULL;
907 fdisk_label_info_t linfo;
908 fdisk_part_t *part;
909 fdisk_part_info_t pinfo;
910 cap_spec_t cap;
911 cap_spec_t mcap;
912 fdisk_dev_flags_t dflags;
913 char *sltype = NULL;
914 char *sdcap = NULL;
915 char *scap = NULL;
916 char *smcap = NULL;
917 char *sfstype = NULL;
918 char *svcname = NULL;
919 char *spkind;
920 const char *label;
921 errno_t rc;
922 int npart;
923 void *sel;
924
925 rc = nchoice_create(&choice);
926 if (rc != EOK) {
927 assert(rc == ENOMEM);
928 printf("Out of memory.\n");
929 goto error;
930 }
931
932 rc = nchoice_set_prompt(choice, "Select action");
933 if (rc != EOK) {
934 assert(rc == ENOMEM);
935 printf("Out of memory.\n");
936 goto error;
937 }
938
939 rc = fdisk_dev_capacity(dev, &cap);
940 if (rc != EOK) {
941 printf("Error getting device capacity.\n");
942 goto error;
943 }
944
945 cap_simplify(&cap);
946
947 rc = cap_format(&cap, &sdcap);
948 if (rc != EOK) {
949 printf("Out of memory.\n");
950 goto error;
951 }
952
953 rc = fdisk_dev_get_svcname(dev, &svcname);
954 if (rc != EOK) {
955 printf("Error getting device service name.\n");
956 goto error;
957 }
958
959 fdisk_dev_get_flags(dev, &dflags);
960
961 printf("Device: %s (%s)\n", svcname, sdcap);
962 free(sdcap);
963 sdcap = NULL;
964
965 rc = fdisk_label_get_info(dev, &linfo);
966 if (rc != EOK) {
967 printf("Error getting label information.\n");
968 goto error;
969 }
970
971 switch (linfo.ltype) {
972 case lt_none:
973 printf("Disk contains no label.\n");
974 break;
975 default:
976 rc = label_type_format(linfo.ltype, &sltype);
977 if (rc != EOK) {
978 assert(rc == ENOMEM);
979 printf("Out of memory.\n");
980 goto error;
981 }
982
983 printf("Label type: %s\n", sltype);
984 free(sltype);
985 sltype = NULL;
986 break;
987 }
988
989 part = fdisk_part_first(dev);
990 npart = 0;
991 while (part != NULL) {
992 ++npart;
993 rc = fdisk_part_get_info(part, &pinfo);
994 if (rc != EOK) {
995 printf("Error getting partition information.\n");
996 goto error;
997 }
998
999 cap_simplify(&pinfo.capacity);
1000
1001 rc = cap_format(&pinfo.capacity, &scap);
1002 if (rc != EOK) {
1003 printf("Out of memory.\n");
1004 goto error;
1005 }
1006
1007 rc = vol_pcnt_fs_format(pinfo.pcnt, pinfo.fstype, &sfstype);
1008 if (rc != EOK) {
1009 printf("Out of memory.\n");
1010 goto error;
1011 }
1012
1013 if (str_size(pinfo.label) > 0)
1014 label = pinfo.label;
1015 else
1016 label = "(No name)";
1017
1018 if (linfo.ltype == lt_none)
1019 printf("Entire disk: %s %s", label, scap);
1020 else
1021 printf("Partition %d: %s %s", npart, label, scap);
1022
1023 if ((linfo.flags & lf_ext_supp) != 0) {
1024 rc = label_pkind_format(pinfo.pkind, &spkind);
1025 if (rc != EOK) {
1026 printf("\nOut of memory.\n");
1027 goto error;
1028 }
1029
1030 printf(", %s", spkind);
1031 free(spkind);
1032 }
1033
1034 if (pinfo.pkind != lpk_extended) {
1035 printf(", %s", sfstype);
1036 }
1037
1038 printf("\n");
1039
1040 free(scap);
1041 scap = NULL;
1042 free(sfstype);
1043 sfstype = NULL;
1044
1045 part = fdisk_part_next(part);
1046 }
1047
1048 /* Display available space */
1049 if ((linfo.flags & lf_can_create_pri) != 0) {
1050 rc = fdisk_part_get_max_avail(dev, spc_pri, &mcap);
1051 if (rc != EOK) {
1052 rc = EIO;
1053 goto error;
1054 }
1055
1056 cap_simplify(&mcap);
1057
1058 rc = cap_format(&mcap, &smcap);
1059 if (rc != EOK) {
1060 rc = ENOMEM;
1061 goto error;
1062 }
1063
1064 if ((linfo.flags & lf_ext_supp) != 0)
1065 printf("Maximum free primary block: %s\n", smcap);
1066 else
1067 printf("Maximum free block: %s\n", smcap);
1068
1069 free(smcap);
1070 smcap = NULL;
1071
1072 rc = fdisk_part_get_tot_avail(dev, spc_pri, &mcap);
1073 if (rc != EOK) {
1074 rc = EIO;
1075 goto error;
1076 }
1077
1078 cap_simplify(&mcap);
1079
1080 rc = cap_format(&mcap, &smcap);
1081 if (rc != EOK) {
1082 rc = ENOMEM;
1083 goto error;
1084 }
1085
1086 if ((linfo.flags & lf_ext_supp) != 0)
1087 printf("Total free primary space: %s\n", smcap);
1088 else
1089 printf("Total free space: %s\n", smcap);
1090
1091 free(smcap);
1092 smcap = NULL;
1093 }
1094
1095 /* Display available space */
1096 if ((linfo.flags & lf_can_create_log) != 0) {
1097 rc = fdisk_part_get_max_avail(dev, spc_log, &mcap);
1098 if (rc != EOK) {
1099 rc = EIO;
1100 goto error;
1101 }
1102
1103 cap_simplify(&mcap);
1104
1105 rc = cap_format(&mcap, &smcap);
1106 if (rc != EOK) {
1107 rc = ENOMEM;
1108 goto error;
1109 }
1110
1111 printf("Maximum free logical block: %s\n", smcap);
1112 free(smcap);
1113 smcap = NULL;
1114
1115 rc = fdisk_part_get_tot_avail(dev, spc_log, &mcap);
1116 if (rc != EOK) {
1117 rc = EIO;
1118 goto error;
1119 }
1120
1121 cap_simplify(&mcap);
1122
1123 rc = cap_format(&mcap, &smcap);
1124 if (rc != EOK) {
1125 rc = ENOMEM;
1126 goto error;
1127 }
1128
1129 printf("Total free logical space: %s\n", smcap);
1130 free(smcap);
1131 smcap = NULL;
1132 }
1133
1134 rc = nchoice_set_prompt(choice, "Select action");
1135 if (rc != EOK) {
1136 assert(rc == ENOMEM);
1137 printf("Out of memory.\n");
1138 goto error;
1139 }
1140
1141 if ((linfo.flags & lf_ext_supp) != 0) {
1142 if ((linfo.flags & lf_can_create_pri) != 0) {
1143 rc = nchoice_add(choice, "Create primary "
1144 "partition",
1145 (void *)devac_create_pri_part, 0);
1146 if (rc != EOK) {
1147 assert(rc == ENOMEM);
1148 printf("Out of memory.\n");
1149 goto error;
1150 }
1151 }
1152
1153 if ((linfo.flags & lf_can_create_ext) != 0) {
1154 rc = nchoice_add(choice, "Create extended "
1155 "partition",
1156 (void *)devac_create_ext_part, 0);
1157 if (rc != EOK) {
1158 assert(rc == ENOMEM);
1159 printf("Out of memory.\n");
1160 goto error;
1161 }
1162 }
1163
1164 if ((linfo.flags & lf_can_create_log) != 0) {
1165 rc = nchoice_add(choice, "Create logical "
1166 "partition",
1167 (void *)devac_create_log_part, 0);
1168 if (rc != EOK) {
1169 assert(rc == ENOMEM);
1170 printf("Out of memory.\n");
1171 goto error;
1172 }
1173 }
1174 } else { /* (linfo.flags & lf_ext_supp) == 0 */
1175 if ((linfo.flags & lf_can_create_pri) != 0) {
1176 rc = nchoice_add(choice, "Create partition",
1177 (void *)devac_create_pri_part, 0);
1178 if (rc != EOK) {
1179 assert(rc == ENOMEM);
1180 printf("Out of memory.\n");
1181 goto error;
1182 }
1183 }
1184 }
1185
1186 if ((linfo.flags & lf_can_modify_part) != 0) {
1187 rc = nchoice_add(choice, "Modify partition",
1188 (void *)devac_modify_part, 0);
1189 if (rc != EOK) {
1190 assert(rc == ENOMEM);
1191 printf("Out of memory.\n");
1192 goto error;
1193 }
1194 }
1195
1196 if ((linfo.flags & lf_can_delete_part) != 0) {
1197 rc = nchoice_add(choice, "Delete partition",
1198 (void *)devac_delete_part, 0);
1199 if (rc != EOK) {
1200 assert(rc == ENOMEM);
1201 printf("Out of memory.\n");
1202 goto error;
1203 }
1204 }
1205
1206 if ((dflags & fdf_can_create_label) != 0) {
1207 rc = nchoice_add(choice, "Create label",
1208 (void *)devac_create_label, 0);
1209 if (rc != EOK) {
1210 assert(rc == ENOMEM);
1211 printf("Out of memory.\n");
1212 goto error;
1213 }
1214 }
1215
1216 if ((dflags & fdf_can_delete_label) != 0) {
1217 rc = nchoice_add(choice, "Delete label",
1218 (void *)devac_delete_label, 0);
1219 if (rc != EOK) {
1220 assert(rc == ENOMEM);
1221 printf("Out of memory.\n");
1222 goto error;
1223 }
1224 }
1225
1226 if ((dflags & fdf_can_erase_dev) != 0) {
1227 rc = nchoice_add(choice, "Erase disk",
1228 (void *)devac_erase_disk, 0);
1229 if (rc != EOK) {
1230 assert(rc == ENOMEM);
1231 printf("Out of memory.\n");
1232 goto error;
1233 }
1234 }
1235
1236 rc = nchoice_add(choice, "Exit", (void *)devac_exit, 0);
1237 if (rc != EOK) {
1238 assert(rc == ENOMEM);
1239 printf("Out of memory.\n");
1240 goto error;
1241 }
1242
1243 rc = nchoice_get(choice, &sel);
1244 if (rc != EOK) {
1245 printf("Error getting user selection.\n");
1246 return rc;
1247 }
1248
1249 switch ((devac_t)sel) {
1250 case devac_create_label:
1251 (void) fdsk_create_label(dev);
1252 break;
1253 case devac_delete_label:
1254 (void) fdsk_delete_label(dev);
1255 break;
1256 case devac_erase_disk:
1257 (void) fdsk_erase_disk(dev);
1258 break;
1259 case devac_create_pri_part:
1260 (void) fdsk_create_part(dev, lpk_primary);
1261 break;
1262 case devac_create_ext_part:
1263 (void) fdsk_create_part(dev, lpk_extended);
1264 break;
1265 case devac_create_log_part:
1266 (void) fdsk_create_part(dev, lpk_logical);
1267 break;
1268 case devac_modify_part:
1269 (void) fdsk_modify_part(dev);
1270 break;
1271 case devac_delete_part:
1272 (void) fdsk_delete_part(dev);
1273 break;
1274 case devac_exit:
1275 quit = true;
1276 break;
1277 }
1278
1279 nchoice_destroy(choice);
1280 return EOK;
1281error:
1282 free(sdcap);
1283 free(scap);
1284 free(smcap);
1285 free(sfstype);
1286 free(svcname);
1287 if (choice != NULL)
1288 nchoice_destroy(choice);
1289 return rc;
1290}
1291
1292int main(int argc, char *argv[])
1293{
1294 service_id_t svcid;
1295 fdisk_dev_t *dev;
1296 errno_t rc;
1297
1298 rc = fdisk_create(&fdisk);
1299 if (rc != EOK) {
1300 printf("Error initializing Fdisk.\n");
1301 return 1;
1302 }
1303
1304 rc = fdsk_dev_sel_choice(&svcid);
1305 if (rc != EOK)
1306 return 1;
1307
1308 if (svcid == 0)
1309 return 0;
1310
1311 rc = fdisk_dev_open(fdisk, svcid, &dev);
1312 if (rc != EOK) {
1313 printf("Error opening device.\n");
1314 return 1;
1315 }
1316
1317 while (!quit) {
1318 rc = fdsk_dev_menu(dev);
1319 if (rc != EOK) {
1320 fdisk_dev_close(dev);
1321 return 1;
1322 }
1323 }
1324
1325 fdisk_dev_close(dev);
1326 fdisk_destroy(fdisk);
1327
1328 return 0;
1329}
1330
1331
1332/** @}
1333 */
Note: See TracBrowser for help on using the repository browser.