source: mainline/uspace/app/fdisk/fdisk.c@ 2d78d88

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

Modifying mount point for a partition.

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