Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/app/fdisk/fdisk.c	(revision 8227d634855cabb163487dd2efe9a1b301377b9d)
@@ -66,8 +66,10 @@
 	char *svcname = NULL;
 	fdisk_cap_t cap;
+	fdisk_dev_info_t *sdev;
 	char *scap = NULL;
 	char *dtext = NULL;
 	service_id_t svcid;
 	void *sel;
+	int ndevs;
 	int rc;
 
@@ -93,6 +95,9 @@
 
 	info = fdisk_dev_first(devlist);
+	ndevs = 0;
 	while (info != NULL) {
-		rc = fdisk_dev_get_svcname(info, &svcname);
+		++ndevs;
+
+		rc = fdisk_dev_info_get_svcname(info, &svcname);
 		if (rc != EOK) {
 			printf("Error getting device service name.\n");
@@ -100,5 +105,5 @@
 		}
 
-		rc = fdisk_dev_capacity(info, &cap);
+		rc = fdisk_dev_info_capacity(info, &cap);
 		if (rc != EOK) {
 			printf("Error getting device capacity.\n");
@@ -138,4 +143,17 @@
 	}
 
+	if (ndevs == 0) {
+		printf("No disk devices found.\n");
+		rc = ENOENT;
+		goto error;
+	}
+
+	rc = nchoice_add(choice, "Exit", NULL);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
 	rc = nchoice_get(choice, &sel);
 	if (rc != EOK) {
@@ -144,8 +162,12 @@
 	}
 
-	fdisk_dev_get_svcid((fdisk_dev_info_t *)sel, &svcid);
+	sdev = (fdisk_dev_info_t *)sel;
+	if (sdev != NULL) {
+		fdisk_dev_info_get_svcid(sdev, &svcid);
+	} else {
+		svcid = 0;
+	}
+
 	fdisk_dev_list_free(devlist);
-
-	printf("Selected dev with sid=%zu\n", svcid);
 
 	nchoice_destroy(choice);
@@ -167,4 +189,6 @@
 	nchoice_t *choice = NULL;
 	void *sel;
+	char *sltype = NULL;
+	int i;
 	int rc;
 
@@ -183,16 +207,18 @@
 	}
 
-	rc = nchoice_add(choice, "GPT", (void *)fdl_gpt);
-	if (rc != EOK) {
-		assert(rc == ENOMEM);
-		printf("Out of memory.\n");
-		goto error;
-	}
-
-	rc = nchoice_add(choice, "MBR", (void *)fdl_mbr);
-	if (rc != EOK) {
-		assert(rc == ENOMEM);
-		printf("Out of memory.\n");
-		goto error;
+	for (i = FDL_CREATE_LO; i < FDL_CREATE_HI; i++) {
+		rc = fdisk_ltype_format(i, &sltype);
+		if (rc != EOK)
+			goto error;
+
+		rc = nchoice_add(choice, sltype, (void *)(uintptr_t)i);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		free(sltype);
+		sltype = NULL;
 	}
 
@@ -212,4 +238,5 @@
 	return EOK;
 error:
+	free(sltype);
 	if (choice != NULL)
 		nchoice_destroy(choice);
@@ -217,4 +244,216 @@
 }
 
+static int fdsk_delete_label(fdisk_dev_t *dev)
+{
+	int rc;
+
+	rc = fdisk_label_destroy(dev);
+	if (rc != EOK) {
+		printf("Error deleting label.\n");
+		return rc;
+	}
+
+	return EOK;
+}
+
+static int fdsk_select_fstype(fdisk_fstype_t *fstype)
+{
+	nchoice_t *choice = NULL;
+	void *sel;
+	char *sfstype;
+	int i;
+	int rc;
+
+	rc = nchoice_create(&choice);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_set_prompt(choice, "Select file system type");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	for (i = FDFS_CREATE_LO; i < FDFS_CREATE_HI; i++) {
+		rc = fdisk_fstype_format(i, &sfstype);
+		if (rc != EOK)
+			goto error;
+
+		rc = nchoice_add(choice, sfstype, (void *)(uintptr_t)i);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		free(sfstype);
+		sfstype = NULL;
+	}
+
+	rc = nchoice_get(choice, &sel);
+	if (rc != EOK) {
+		printf("Error getting user selection.\n");
+		goto error;
+	}
+
+	nchoice_destroy(choice);
+	*fstype = (fdisk_fstype_t)sel;
+	return EOK;
+error:
+	free(sfstype);
+	if (choice != NULL)
+		nchoice_destroy(choice);
+	return rc;
+}
+
+static int fdsk_create_part(fdisk_dev_t *dev)
+{
+	int rc;
+	fdisk_part_spec_t pspec;
+	fdisk_cap_t cap;
+	fdisk_fstype_t fstype;
+	tinput_t *tinput = NULL;
+	char *scap;
+
+	tinput = tinput_new();
+	if (tinput == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = tinput_set_prompt(tinput, "?> ");
+	if (rc != EOK)
+		goto error;
+
+	while (true) {
+		printf("Enter capacity of new partition.\n");
+		rc = tinput_read(tinput, &scap);
+		if (rc != EOK)
+			goto error;
+
+		rc = fdisk_cap_parse(scap, &cap);
+		if (rc == EOK)
+			break;
+	}
+
+	tinput_destroy(tinput);
+
+	rc = fdsk_select_fstype(&fstype);
+	if (rc != EOK)
+		goto error;
+
+	fdisk_pspec_init(&pspec);
+	pspec.capacity = cap;
+	pspec.fstype = fstype;
+
+	rc = fdisk_part_create(dev, &pspec, NULL);
+	if (rc != EOK) {
+		printf("Error creating partition.\n");
+		goto error;
+	}
+
+	return EOK;
+error:
+	if (tinput != NULL)
+		tinput_destroy(tinput);
+	return rc;
+}
+
+static int fdsk_delete_part(fdisk_dev_t *dev)
+{
+	nchoice_t *choice = NULL;
+	fdisk_part_t *part;
+	fdisk_part_info_t pinfo;
+	char *scap = NULL;
+	char *sfstype = NULL;
+	char *sdesc = NULL;
+	void *sel;
+	int rc;
+
+	rc = nchoice_create(&choice);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_set_prompt(choice, "Select partition to delete");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	part = fdisk_part_first(dev);
+	while (part != NULL) {
+		rc = fdisk_part_get_info(part, &pinfo);
+		if (rc != EOK) {
+			printf("Error getting partition information.\n");
+			goto error;
+		}
+
+		rc = fdisk_cap_format(&pinfo.capacity, &scap);
+		if (rc != EOK) {
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
+		if (rc != EOK) {
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		rc = asprintf(&sdesc, "%s, %s", scap, sfstype);
+		if (rc < 0) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = nchoice_add(choice, sdesc, (void *)part);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		free(scap);
+		scap = NULL;
+		free(sfstype);
+		sfstype = NULL;
+		free(sdesc);
+		sdesc = NULL;
+
+		part = fdisk_part_next(part);
+	}
+
+	rc = nchoice_get(choice, &sel);
+	if (rc != EOK) {
+		printf("Error getting user selection.\n");
+		goto error;
+	}
+
+	rc = fdisk_part_destroy((fdisk_part_t *)sel);
+	if (rc != EOK) {
+		printf("Error deleting partition.\n");
+		return rc;
+	}
+
+	nchoice_destroy(choice);
+	return EOK;
+error:
+	free(scap);
+	free(sfstype);
+	free(sdesc);
+
+	if (choice != NULL)
+		nchoice_destroy(choice);
+	return rc;
+}
+
 /** Device menu */
 static int fdsk_dev_menu(fdisk_dev_t *dev)
@@ -222,6 +461,14 @@
 	nchoice_t *choice = NULL;
 	fdisk_label_info_t linfo;
+	fdisk_part_t *part;
+	fdisk_part_info_t pinfo;
+	fdisk_cap_t cap;
 	char *sltype = NULL;
-	int rc;
+	char *sdcap = NULL;
+	char *scap = NULL;
+	char *sfstype = NULL;
+	char *svcname = NULL;
+	int rc;
+	int npart;
 	void *sel;
 
@@ -240,4 +487,22 @@
 	}
 
+	rc = fdisk_dev_capacity(dev, &cap);
+	if (rc != EOK) {
+		printf("Error getting device capacity.\n");
+		goto error;
+	}
+
+	rc = fdisk_cap_format(&cap, &sdcap);
+	if (rc != EOK) {
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = fdisk_dev_get_svcname(dev, &svcname);
+	if (rc != EOK) {
+		printf("Error getting device service name.\n");
+		goto error;
+	}
+
 	rc = fdisk_label_get_info(dev, &linfo);
 	if (rc != EOK) {
@@ -253,7 +518,41 @@
 	}
 
+	printf("Device: %s, %s\n", sdcap, svcname);
 	printf("Label type: %s\n", sltype);
 	free(sltype);
 	sltype = NULL;
+	free(sdcap);
+	sdcap = NULL;
+
+	part = fdisk_part_first(dev);
+	npart = 0;
+	while (part != NULL) {
+		++npart;
+		rc = fdisk_part_get_info(part, &pinfo);
+		if (rc != EOK) {
+			printf("Error getting partition information.\n");
+			goto error;
+		}
+
+		rc = fdisk_cap_format(&pinfo.capacity, &scap);
+		if (rc != EOK) {
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		rc = fdisk_fstype_format(pinfo.fstype, &sfstype);
+		if (rc != EOK) {
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		printf("Partition %d: %s, %s\n", npart, scap, sfstype);
+		free(scap);
+		scap = NULL;
+		free(sfstype);
+		sfstype = NULL;
+
+		part = fdisk_part_next(part);
+	}
 
 	rc = nchoice_set_prompt(choice, "Select action");
@@ -262,4 +561,24 @@
 		printf("Out of memory.\n");
 		goto error;
+	}
+
+	if (linfo.ltype != fdl_none) {
+		rc = nchoice_add(choice, "Create partition",
+		    (void *)devac_create_part);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+	}
+
+	if (npart > 0) {
+		rc = nchoice_add(choice, "Delete partition",
+		    (void *)devac_delete_part);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
 	}
 
@@ -280,20 +599,4 @@
 			goto error;
 		}
-	}
-
-	rc = nchoice_add(choice, "Create partition",
-	    (void *)devac_create_part);
-	if (rc != EOK) {
-		assert(rc == ENOMEM);
-		printf("Out of memory.\n");
-		goto error;
-	}
-
-	rc = nchoice_add(choice, "Delete partition",
-	    (void *)devac_delete_part);
-	if (rc != EOK) {
-		assert(rc == ENOMEM);
-		printf("Out of memory.\n");
-		goto error;
 	}
 
@@ -318,11 +621,17 @@
 		break;
 	case devac_delete_label:
-		rc = fdisk_label_destroy(dev);
+		rc = fdsk_delete_label(dev);
 		if (rc != EOK)
 			goto error;
 		break;
 	case devac_create_part:
+		rc = fdsk_create_part(dev);
+		if (rc != EOK)
+			goto error;
 		break;
 	case devac_delete_part:
+		rc = fdsk_delete_part(dev);
+		if (rc != EOK)
+			goto error;
 		break;
 	case devac_exit:
@@ -334,4 +643,8 @@
 	return EOK;
 error:
+	free(sdcap);
+	free(scap);
+	free(sfstype);
+	free(svcname);
 	if (choice != NULL)
 		nchoice_destroy(choice);
@@ -349,4 +662,7 @@
 		return 1;
 
+	if (svcid == 0)
+		return 0;
+
 	rc = fdisk_dev_open(svcid, &dev);
 	if (rc != EOK) {
