Anonymous avatar Anonymous committed 2bb3073

Comments (0)

Files changed (1)

 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif
-/* Set the default device, if not set
-   Should respect the platform for which cfdisk is compiled */
-#ifndef DEFAULT_DEVICE
-#define DEFAULT_DEVICE "/dev/hda"
-#define ALTERNATE_DEVICE "/dev/sda"
-#endif
+
 
 
 #define K	1000
 /*int curses_ready = 0;*/
 
 
-void
+static void
 do_quit(int status, const char *message) {
 	endwin();
 	if (message) {
 	exit(status);
 }
 
-void
-clear_status() {
-	move(LINES-1,0);
+
+static int
+get_center(const char *string) {
+	int x = strlen(string);
+	x = MIN(x,COLS);
+	x = (COLS-x)/2;
+	return x;
+}
+
+static void
+clear_status(int sub) {
+	move(LINES-1-(sub==0),0);
 	clrtoeol();
 }
+
+
+
 void
-set_status(const char *status) {
-	int x = (COLS-strlen(status))/2;
-	if (x < 0) x = 0; /* We should make sure that this is not negative, for a very long string */
-	clear_status();
+set_status(const char *status, int sub) {
+	clear_status(sub);
 	/*attron(A_REVERSE);*/
-	move(LINES-1,0);
-	mvaddstr(LINES-1, x ,status);
+	move(LINES-1-(sub==0),0);
+	mvaddstr(LINES-1-(sub==0), get_center(status) ,status);
 	/*attroff(A_REVERSE);*/
 }
 
 void
-print_warning(const char *status) {
-	set_status(status);
+print_warning(const char *status, int sub) {
+	set_status(status,sub);
 	putchar(BELL);
 }
 
 	move(y,0);
 	clrtoeol();
 	for (i = 0; items[i].name; i++) {
-		/*while (items[i].name && !strchr(keys,tolower(items[i].key))) i++;
-		if (!items[i].name) break;*/
-		char buf[item_size+2];
-		int name_len;
-		const char *name;
-
-		/* Localize the text. Translate empty string to empty string. */
-		name = (items[i].name[0] ? _(items[i].name) : "");
-
-		name_len = strlen(name);
-		/* Enclose the text if the type is a button. If it is too long, cut. */
-		if (name_len >= item_len) {
-			snprintf(buf, item_size+1, (type & MENU_BUTTON) ? "[%s]" : "%s" , name);
-			if (type & MENU_BUTTON) {
-				buf[item_size-1] = ']';
-				buf[item_size] = '\0';
+		if (strchr(keys,tolower(items[i].key))) {
+			char buf[item_size+2];
+			int name_len;
+			const char *name;
+	
+			/* Localize the text. Translate empty string to empty string. */
+			name = (items[i].name[0] ? _(items[i].name) : "");
+	
+			name_len = strlen(name);
+			/* Enclose the text if the type is a button. If it is too long, cut. */
+			if (name_len >= item_len) {
+				snprintf(buf,item_size+1, (type & MENU_BUTTON) ? "[%s]" : "%s" , name);
+				if (type & MENU_BUTTON) {
+					buf[item_size-1] = ']';
+					buf[item_size] = '\0';
+				}
 			}
+			else {
+				snprintf(buf,item_size+1, (type & MENU_BUTTON) ? "[%*s%s%*s]" : "%*s%s%*s" ,
+				(item_len - name_len)/2, "", name, (item_len - name_len + 1)/2 , "");
+			}
+	
+			/* Write the button. Highlight if is selected. */
+			
+			if (i == selected) attron(A_STANDOUT);
+			/*else if (strchr(keys,tolower(items[i].key))) attron(A_DIM);*/
+	
+			mvaddstr(y,x,buf);
+	
+			if (i == selected) attroff(A_STANDOUT);
+			/*else if (strchr(keys,tolower(items[i].key))) attroff(A_BOLD);*/
+			
+			if (x + 2*item_size + 2*MENUDIV < COLS) {
+				x += item_size + MENUDIV;
+			}
+			else if (y + 3 < LINES) { /* y + 1 < LINES - 2 */
+				y++;
+				x = MENUDIV;
+				move(y,0);
+				clrtoeol();
+			}
+			/* If we can't draw all the menu items, end. */
+			else break;
 		}
-		else {
-			snprintf(buf, item_size+1, (type & MENU_BUTTON) ? "[%*s%s%*s]" : "%*s%s%*s" ,
-				(item_len - name_len)/2, "", name, (item_len - name_len + 1)/2 , "");
-		}
-
-		/* Write the button. Highlight if is selected. */
-		
-		if (i == selected) attron(A_STANDOUT);
-		/*else if (strchr(keys,tolower(items[i].key))) attron(A_DIM);*/
-
-		mvaddstr(y,x,buf);
-
-		if (i == selected) attroff(A_STANDOUT);
-		/*else if (strchr(keys,tolower(items[i].key))) attroff(A_BOLD);*/
-		
-		if (x + 2*item_size + 2*MENUDIV < COLS) {
-			x += item_size + MENUDIV;
-		}
-		else if (y + 3 < LINES) { /* y + 1 < LINES - 2 */
-			y++;
-			x = MENUDIV;
-			move(y,0);
-			clrtoeol();
-		}
-		/* If we can't draw all the menu items, end. */
-		else break;
 	}
 	while (++y < LINES-2) {
 		move(y,0);
 	/* If the selected item exits, print its description */
 	if (selected < i) {
 		desc = _(items[selected].desc);
-		set_status(desc);
+		set_status(desc,1);
 	}
 	refresh;
 }
 			if (key == '[' || key == 'O') {
 				key = getch();
 				if (key == 'A') { /* ^[[A = Up arrow */
-					key = DOWN_KEY;
+					key = UP_KEY;
 				}
 				else if (key == 'B') {	/* ^[[B = Down arrow */
-					key = UP_KEY;
+					key = DOWN_KEY;
 				}
 				else if (key == 'C') {	/* ^[[C = Right arrow */
 					do {
 		/* If the pressed key is in the list of accepted keys, print a warning */
 		if(!(type & MENU_ANYKEY) && !strchr(keys,tolower(key))) {
 			key = 0;
-			print_warning(_("Invalid key"));
+			print_warning(_("Invalid key"),0);
 		}
 	}
 	return key;
 				move(y,x);
 			}
 			else
-				print_warning(_("No more characters to delete"));
+				print_warning(_("No more characters to delete"),1);
 		}
 		else if (key == CR) {
 			done = 1;
 				mvaddch(y,x++,key);
 			}
 			else
-				print_warning(_("String too long"));
+				print_warning(_("String too long"),1);
 		}
 		refresh();
 	}
 	return 1;
 	
 }
+
+
 UICalls uiquery;
-
-
 static int
 getbool(const char* prompt, int* value) {
 	int result;
 init_calls() {
 	uiquery.getbool = getbool;
 	uiquery.getstring = getstring;
+	uiquery.need_commit = 0;
 }
 
+/* Define column positions. The first three will be fixed. */
+#define col_name 3
+#define col_flags 12
+#define col_type 23
+#define col_fs 35
+
+/* Partition list drawing function */
+void
+plist_draw (PedDisk *cdisk, PedPartition *selected) {
+	PedPartition *part;
+	const char* temp;
+	char buf[SMALLBUF];
+	int col_label = ((float)53/(80-col_fs))*(COLS-col_fs);
+	int col_size = ((float)66/(80-col_fs))*(COLS-col_fs);
+	int i,x,y = INFOSIZE;
+	
+	move(y++,0); clrtoeol();
+	/* Display header */
+	move(y,0); clrtoeol();
+	mvaddstr(y,col_name,N_("Number"));
+	mvaddstr(y,col_flags,N_("Flags"));
+	mvaddstr(y,col_type,N_("Part Type"));
+	mvaddstr(y,col_fs,N_("Filesystem"));
+	mvaddstr(y,col_label,N_("Label"));
+	/* We want size to be right aligned */
+	temp = N_("Size");
+	x = COLS-strlen(temp)-2;
+	x = MAX(x,col_size);
+	mvaddstr(y++,x,temp);
+	buf[0] = ' ';
+	for (i = 1; i < COLS-1 && i < SMALLBUF; i++) {
+		buf[i] = '-';
+	}
+	if (i < SMALLBUF) buf[i++] = ' ';
+	if (i < SMALLBUF) buf[i] = '\0';
+	mvaddstr(y++,0,buf);
+	for (part = ped_disk_next_partition (cdisk, NULL); part;
+	     part = ped_disk_next_partition (cdisk, part)) {
+		if (part->type & PED_PARTITION_METADATA) continue;
+		int free = 0;
+		if (part == selected) attron(A_STANDOUT);
+		snprintf(buf, SMALLBUF, "%*d%*s", col_name+4,part->num, col_flags-col_name-4, "");
+		mvaddstr(y,0,buf);
+
+		snprintf(buf, SMALLBUF, "%-*s", col_type-col_flags,
+		         (ped_partition_get_flag(part, PED_PARTITION_BOOT) ? N_("Bootable") : ""));
+		mvaddstr(y,col_flags,buf);
+		if (part->type & PED_PARTITION_EXTENDED)
+			temp = N_("Extended");
+		else if (part->type & PED_PARTITION_LOGICAL)
+			temp = N_("Logical");
+		else if (part->type & PED_PARTITION_FREESPACE) {
+			free = 1;
+			temp = N_("None"); /* FIXME: Make this like Linux cfdisk */
+		}
+
+		else temp = N_("Primary");
+		snprintf(buf, SMALLBUF, "%-*s", col_fs-col_type, temp);
+		mvaddstr(y,col_type,buf);
+		temp = "";
+		if(part->fs_type)
+			temp = part->fs_type->name;
+		snprintf(buf, SMALLBUF, "%-*s", col_label-col_fs, temp);
+
+		mvaddstr(y,col_fs,buf);
+		temp = NULL;
+		if (ped_disk_type_check_feature(cdisk->type,PED_DISK_TYPE_PARTITION_NAME))
+			temp = ped_partition_get_name(part);
+		if (!temp) temp = "";
+		snprintf(buf, SMALLBUF, "%-*s", col_size-col_label, temp);
+		mvaddstr(y,col_label,buf);
+		snprintf(buf, SMALLBUF, "%*s ", COLS-col_size-1,
+		         ped_unit_format (part->disk->dev, part->geom.length));
+		mvaddstr(y++,col_size,buf);
+		if (part == selected) attroff(A_STANDOUT);
+	}
+}
+
+static struct MenuItem part_menu[] = {
+	{ 'b', N_("Bootable"), N_("Toggle bootable flag of the current partition") },
+	{ 'n', N_("New"), N_("Create new partition from free space") },
+	{ 's', N_("Rescue"), N_("Look for partitions in the free space") },
+	{ 'f', N_("Format"), N_("Formats the partition with a filesystem") },
+	{ 'c', N_("Check"), N_("Check partition for consistency") },
+	{ 'a', N_("Rename"), N_("Change partition name") },
+	{ 'y', N_("Copy"), N_("Write another partition over this one (requires commit)") },
+	{ 'r', N_("Resize"), N_("Resizes the current partition (requires commit)") },
+	{ 'o', N_("Move"), N_("Moves the current partition (requires commit)") },
+	{ 'd', N_("Delete"), N_("Delete the current partition") },
+	{ 't', N_("Type"), N_("Change the filesystem type") },
+	{ 'u', N_("Units"), N_("Change units of the partition size display") },
+	{ 'w', N_("Commit"), N_("Write the changes to the disk") },
+	{ 'q', N_("Quit"), N_("Quit program without writing partition table") },
+	{ 'p', N_("Print"), N_("Print partition table to the screen or to a file") },
+	{ 'h', N_("Help"), N_("Display help") },
+        { 0, NULL, NULL }
+};
+
+
+
+/* FIXME: This is *ugly*. Fix it. Can be fixed with a expand/collapse
+          list of logical partitions. At least it works. */
+static PedPartition *
+disk_get_prev_nmd_partition(PedDisk *cdisk, PedPartition *part) {
+	PedPartition *temp_a, *temp_b;
+	temp_a = NULL;
+	/*do {
+		temp_a = ped_disk_next_partition(cdisk,temp_a);
+	} while (temp_a || temp_a->type & PED_PARTITION_METADATA);*/
+	temp_b = temp_a;
+	do {
+		if (ped_disk_next_partition(cdisk,temp_b) == part)
+			break;
+		temp_b = ped_disk_next_partition(cdisk,temp_b);
+		if (!temp_b || !(temp_b->type & PED_PARTITION_METADATA))
+			temp_a = temp_b;
+	} while (temp_b);
+	return temp_a;
+}
+
+const char keys_ext[] = { 'd','u','w','q','p','h',UP_KEY,DOWN_KEY, '\0' };
+const char keys_free[] = { 'n','r','u','w','q','p','h',UP_KEY,DOWN_KEY, '\0' };
+const char keys_part[] = { 'b','f','c','a','y','r','o','d','t','u','w','q','p','h',UP_KEY,DOWN_KEY, '\0' };
+/*bfcayrodtuwqph*/
+
+static int
+do_plist (PedDisk *cdisk) {
+	int key = 0, i, redraw = 1;
+	const char* keys;
+	PedPartition *selected = NULL;
+	PedPartition *temp,*memp;
+	do {
+		selected = ped_disk_next_partition(cdisk,selected);
+	} while (selected && selected->type & PED_PARTITION_METADATA);
+	while (!key) {
+		if(redraw) {
+			plist_draw(cdisk,selected);
+			redraw = 0;
+		}
+		if (selected->type & PED_PARTITION_EXTENDED)
+			keys = keys_ext;
+		else if (selected->type & PED_PARTITION_FREESPACE)
+			keys = keys_free;
+		else keys = keys_part;
+		
+		key = do_menu(part_menu, 8, MENU_BUTTON, keys, 0);
+		if (key == UP_KEY) {
+
+			temp = disk_get_prev_nmd_partition(cdisk,selected);
+			if (temp) {
+				selected = temp;
+				redraw = 1;
+			}
+			/* FIXME: Make the menu drawing clear these more carefully. */
+			else print_warning(N_("No more partitions"),1);
+			key = 0;
+		}
+		if (key == DOWN_KEY) {
+			temp = ped_disk_next_partition(cdisk,selected);
+			while (temp && temp->type & PED_PARTITION_METADATA)
+				temp = ped_disk_next_partition(cdisk,temp);
+			if (temp) { 
+				selected = temp;
+				redraw = 1;
+			}
+			else print_warning(N_("No more partitions"),1);
+			key = 0;
+		}
+		if (key == ESC || key == 'q') {
+			if (uiquery.need_commit) {
+				key = 0;
+				getbool(N_("Partition table has changed, are you sure you want to quit?"),
+				        &key);
+			}
+		}
+		refresh();
+	}
+	
+}
+
+
 PedDevice *dev;
 PedDisk *disk;
 char *devname;
 char *info_sectors;
 char *info_cylsize;
 static void
+
+
 show_info() {
-	int x,y,n;
+	int y;
 	char buf[SMALLBUF];
 	for (y = 0; y < INFOSIZE+1; y++) {
 		move(y,0);
 		clrtoeol();
 	}
 	y = 0;
-	snprintf(buf,SMALLBUF,"cfdisk %s",CFDISK_VERSION);
-	n = strlen(buf);
-	n = MIN(n,COLS);
-	x = (COLS-n)/2;
-	mvaddstr(y++,x,buf);
+	snprintf(buf,SMALLBUF,"GNU cfdisk %s",CFDISK_VERSION);
+	mvaddstr(y++,get_center(buf),buf);
+	y++;
 	
-	if (info_model) {
-		n = strlen(info_model);
-		n = MIN(n,COLS);
-		x = (COLS-n)/2;
-		mvaddstr(y++,x,info_model);
-	}
+	if (info_model) 
+		mvaddstr(y++,get_center(info_model),info_model);
 	
 	if (info_size) {
 		snprintf(buf,SMALLBUF,"Disk: %s   Size: %s", devname, info_size);
 	else {
 		snprintf(buf,SMALLBUF,"Disk: %s", devname);
 	}
-	n = strlen(buf);
-	n = MIN(n,COLS);
-	x = (COLS-n)/2;
-	mvaddstr(y++,x,buf);
+	mvaddstr(y++,get_center(buf),buf);
 	
 	if (info_heads && info_sectors && info_cylinders) {
 		snprintf(buf,SMALLBUF, "Heads: %s   Sectors per track: %s   Cylinders: %s",
 				info_heads, info_sectors, info_cylinders);
-		n = strlen(buf);
-		n = MIN(n,COLS);
-		x = (COLS - n) /2;
-		mvaddstr(y++,x,buf);
+		mvaddstr(y++,get_center(buf),buf);
 	}
 	
 	
 }
 
+
+
+
 static void
 init_disk() {
 	char buf[SMALLBUF];
 				do_quit(1,_("Invalid device"));
 			}
 		}
-		else  do_quit(0,NULL);
+		else do_quit(0,NULL);
 	}
 	disk = ped_disk_new(dev);
 	if (!disk) {
 			if (!do_mklabel (dev, &disk, NULL, &uiquery))
 				do_quit(1,_("Creation of partition table failed"));
 		}
+		else do_quit (0,NULL);
 	}
-	ped_unit_set_default(PED_UNIT_BYTE);
+	ped_unit_set_default(PED_UNIT_MEGABYTE);
 
-	snprintf(buf,SMALLBUF,_("%s bytes, %s MB"),
+	snprintf(buf,SMALLBUF,_("%s, %s"),
 		ped_unit_format_custom_byte (dev, dev->length * dev->sector_size-1, PED_UNIT_BYTE),
 		ped_unit_format_custom_byte (dev, dev->length * dev->sector_size-1, PED_UNIT_MEGABYTE));
 	n = strlen(buf);
 	n = strlen(buf);
 	info_sectors = calloc(n,sizeof(char));
 	strncpy(info_sectors,buf,n);
-	/*
-                printf (_("BIOS cylinder,head,sector geometry: %d,%d,%d.  "
-                          "Each cylinder is %s.\n"),
-                        chs->cylinders, chs->heads, chs->sectors, cyl_size);
-                ped_free (cyl_size); */
+
 }
 
 static void
 print_info(void) {
 	
 }
-static struct MenuItem part_menu[] = {
-	{ 'b', N_("Bootable"), N_("Toggle bootable flag of the current partition") },
-	{ 'n', N_("New"), N_("Create new partition from free space") },
-	{ 's', N_("Rescue"), N_("Look for partitions in the free space") },
-	{ 'f', N_("Format"), N_("Formats the partition with a filesystem") },
-	{ 'c', N_("Check"), N_("Check partition for consistency") },
-	{ 'a', N_("Rename"), N_("Change partition name") },
-	{ 'y', N_("Copy"), N_("Write another partition over this one (requires commit)") },
-	{ 'r', N_("Resize"), N_("Resizes the current partition (requires commit)") },
-	{ 'o', N_("Move"), N_("Moves the current partition (requires commit)") },
-	{ 'd', N_("Delete"), N_("Delete the current partition") },
-	{ 't', N_("Type"), N_("Change the filesystem type") },
-	{ 'u', N_("Units"), N_("Change units of the partition size display") },
-	{ 'w', N_("Commit"), N_("Write the changes to the disk") },
-	{ 'q', N_("Quit"), N_("Quit program without writing partition table") },
-	{ 'p', N_("Print"), N_("Print partition table to the screen or to a file") },
-	{ 'h', N_("Help"), N_("Display help") },
-        { 0, NULL, NULL }
-};
-
 
 
 static void
 	uiquery.getbool(value,&test);
 	free(value);*/
 	show_info();
-	do_menu(part_menu, 8, MENU_BUTTON, "bfcayrodtuwqph", 0);
+	do_plist(disk);
+	plist_draw(disk,NULL);
 	endwin();
 }
 int
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.