Anonymous avatar Anonymous committed 218fc36

Commit of some small changes. Make copy work. (fdisk@sv.gnu.org/fdisk--main--0--patch-11)
fdisk@sv.gnu.org/fdisk--main--0--patch-11
Keywords:

Comments (0)

Files changed (3)

 
 
 /* struct for a menu item. I got the idea from Linux cfdisk. Every action is bound to a key. */
-struct MenuItem {
+struct _MenuItem {
 	char key;
 	const char *name;
 	const char *desc; 
 };
+typedef struct _MenuItem MenuItem;
 
 
 PedDevice *dev;
 
 /* Menu drawing function */
 void
-menu_draw (struct MenuItem *items, int item_len, MenuOptions opts, const char *keys, int selected) {
+menu_draw (MenuItem *items, int item_len, MenuOptions opts, const char *keys, int selected) {
 	int i, y = LINES - 2 - MENUSIZE + (opts & MENU_TITLE ? 1 : 0), x = MENUDIV;
 	int item_size = item_len + (opts & MENU_BUTTON ? 2 : 0);
 	const char *desc;
 /* Menu display function. The selected parameter specifies the item that is selected by
  * default and the keys string includes the keys that should be accepted by the interface. */
 static int
-do_menu (struct MenuItem *items, int item_len, MenuOptions opts, const char *keys, int selected) {
+do_menu (MenuItem *items, int item_len, MenuOptions opts, const char *keys, int selected) {
 	int i, key = 0, count = 0, redraw = 1;
 	
 	/* Count the items and make sure that the selected item is available */
 	} 
 }
 static void show_info();
-void plist_draw (PedDisk *cdisk, PedPartition *selected, int selnum, int *start);
+static void plist_draw (PedDisk *cdisk, PedPartition *selected, int selnum, int *start);
+static int do_plist (PedDisk *cdisk, PedPartition **part);
 
 static const StrList*
 do_strlist (const char *prompt, const StrList *strlist) {
 	else i = 0;
 	buf[i] = '\0';
 	mvaddstr(y,MENUDIV,prompt); addstr(": ");
+	getyx(stdscr,y,x);
+	n = MIN(n,COLS-x);
 	addstr(buf);
 	getyx(stdscr,y,x);
-	n = MIN(n,COLS-x);
+	
 	refresh();
 	while(!done) {
 		key = getch();
 		refresh();
 	}
 	if (*value) ped_free (*value);
-	n = strlen(buf);
-	*value = (char *)calloc(n,sizeof(char));
-	strncpy(*value,buf,n);
+	*value = strdup(buf);
+	//n = strlen(buf);
+	//*value = (char *)calloc(n,sizeof(char));
+	//strncpy(*value,buf,n);
 	return 1;
 	
 }
 static int
 getbool(const char* prompt, int* value) {
 	int result;
-	struct MenuItem yes_no[] = {
+	MenuItem yes_no[] = {
 		{'y', N_("Yes"), "" },
 		{'n', N_("No"), "" },
 		{0, NULL, NULL }
 	else return read_char(prompt,value);
 }
 
+static int
+getpart (const char* prompt, PedDisk **disk, PedPartition **value) {
+	if (!*disk) {
+		return 0; /* TODO, although it might not get used */
+	}
+	menu_title(prompt);
+	return do_plist(*disk,value);
+}
 
 
 static PedExceptionOption
 exception_handler (PedException* ex) {
-	static struct MenuItem ex_choices[] = {
+	static MenuItem ex_choices[] = {
 		{ 'f', N_("Fix"), "" },
 		{ 'y', N_("Yes"), "" },
 		{ 'n', N_("No"), "" },
 		         tcontext->predicted_time_left / 60,
 		         tcontext->predicted_time_left % 60); 
 		set_status(buf,1);
+		refresh();
         }
 
 }
 init_calls() {
 	uiquery.getbool = getbool;
 	uiquery.getstring = getstring;
+	uiquery.getpart = getpart;
 	uiquery.need_commit = 0;
 	uiquery.timer = ped_timer_new (_timer_handler, &timer_context);
 	ped_exception_set_handler(exception_handler);
 
 static void
 notice_waitkey(const char *warning) {
-	static struct MenuItem waitkey[] = {
+	static MenuItem waitkey[] = {
 		{ 'k', "", N_("Press any key to continue") },
 		{ 0, NULL, NULL }
 	};
 /* Here we define our menu operations */
 static int
 action_new (PedPartition **part) {
-	static struct MenuItem part_position[] = {
+	static MenuItem part_position[] = {
 		{ 'b', N_("Begining"), N_("Create the partition at the begining of the free space") },
 		{ 'e', N_("End"), N_("Create the partition at the end of the free space") },
 		{ 'c', N_("Custom"), N_("Select custom start and end position of the partition") },
 		{ ESC, N_("Cancel"), N_("Do not create a partition") },
 		{ 0, NULL, NULL }
 	};
-	static struct MenuItem part_type[] = {
+	static MenuItem part_type[] = {
 		{ 'p', N_("Primary"), N_("Create primary partition") },
 		{ 'e', N_("Extended"), N_("Create extended partition") },
 		{ ESC, N_("Cancel"), N_("Do not create a partition") },
 				success = do_mkpart(disk, start, start+length-1, type, NULL, part, UI_DEFAULT,&uiquery);
 			}
 			else if (key == 'e') {
-				success = do_mkpart(disk, end-length, end, type, NULL, part, UI_DEFAULT, &uiquery);
+				success = do_mkpart(disk, end-length+1, end, type, NULL, part, UI_DEFAULT, &uiquery);
 			}
 		}
 	}
 
 static int
 action_mkfs (PedPartition **part) {
-	if (!do_mkfs (disk, *part, NULL, UI_WARN_COMMIT, &uiquery)) {
+	char buf[SMALLBUF];
+	const PedFileSystemType *type = NULL;
+	int go;
+	if ((*part)->fs_type) {
+		go = 1;
+		snprintf(buf,SMALLBUF,_("The partition has %s set as a filesystem. Use it?"),
+		         (*part)->fs_type->name);
+		getbool(buf,&go);
+		if (go) type = (*part)->fs_type;
+	}
+	if (!do_mkfs (disk, *part, type, UI_WARN_COMMIT, &uiquery)) {
 		warning_waitkey(N_("Partition not formatted successfully"));
 		return 0;
 	}
 }
 
 static int
+action_rescue(PedPartition **part) {
+	static MenuItem rescue_menu[] = {
+		{ 'g', N_("Continue"), N_("Proceed with the rescue") },
+		{ 'c', N_("Custom"), N_("Select custom area to look for partitions (for experts only)") },
+		{ ESC, N_("Cancel"), N_("Return to the main menu") },
+		{ 0, NULL, NULL }
+	};
+	const char keys[] = { 'g', 'c', ESC, '\0' };
+	int key;
+	menu_title(_("This will try to rescue broken or deleted partitions")); 
+	key = do_menu(rescue_menu, 8, MENU_BUTTON | MENU_TITLE, keys, 0);
+	if (key == ESC) return 0;
+	if(!do_rescue (disk, (*part)->geom.start, (*part)->geom.end, 
+	           UI_WARN_COMMIT | (key == 'c' ? UI_CUSTOM_VALUES : 0), &uiquery)) {
+		warning_waitkey(N_("There was an error during rescue"));
+		return 0;
+	}
+	notice_waitkey(N_("Finished looking for partitions"));
+	return 1;
+}
+
+static int
+action_copy(PedPartition **part) {
+	if (!do_cp(disk,*part, UI_WARN_COMMIT, &uiquery)) {
+		warning_waitkey(N_("Partition not copied successfully"));
+		return 0;
+	}
+	notice_waitkey(N_("Partition copied successfully"));
+	return 1;
+}
+
+static int
 action_commit () {
 	if (!do_commit(disk,&uiquery)) {
 		warning_waitkey(N_("Commit failed."));
 
 static int
 action_units () {
-	static struct MenuItem units[] = {
+	static MenuItem units[] = {
 		{ '1' , N_("Sectors"), N_("Show the sizes in sectors") },
 		{ '2' , N_("Bytes"), N_("Show the sizes in bytes") },
 		{ '3' , N_("Kilobytes"), N_("Use 1000 bytes as unit size") },
 #define col_fs 35
 
 /* Partition list drawing function */
-void
+static void
 plist_draw (PedDisk *cdisk, PedPartition *selected, int selnum, int *start) {
 	PedPartition *part;
 	const char* temp;
 		mvaddstr(y,0,buf);
 		/* ped_partition_get_flag(part, PED_PARTITION_BOOT) throws an exception when ran on a
 		   free space. */
+		/* FIXME: This blows up on different partition types */
 		snprintf(buf, SMALLBUF, "%-*s", col_type-col_flags,
 		         (!free && ped_partition_is_flag_available(part, PED_PARTITION_BOOT) && 
 		         ped_partition_get_flag(part, PED_PARTITION_BOOT) ? N_("Bootable") : ""));
 	refresh();
 }
 
-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 }
-};
-
-
 /* Get previous non-METADATA partition. Needed for menu navigation */
 /* FIXME: This is *ugly*. Fix it. Can be fixed with a expand/collapse
           list of logical partitions. At least it works. */
 	return temp_a;
 }
 
+static MenuItem main_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 deleted and corrupted 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 }
+};
+
 const char keys_ext[] = { 'd','u','w','q','p','h',UP_KEY,DOWN_KEY, '\0' };
 const char keys_free[] = { 'n','s','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 MenuItem partselect_menu[] = {
+	{ 's', N_("Select"), N_("Select this as the source partition") },
+	{ ESC, N_("Cancel"), N_("Abort partition copy") },
+	{ 0, NULL, NULL }
+};
+
+const char keys_partselect[] = { 's', ESC, UP_KEY, DOWN_KEY, '\0' };
+const char keys_cantselect[] = { ESC, UP_KEY, DOWN_KEY, '\0' };
+
+/* We need to separate this to use the partition list for other purposes like partition copy */
+/* FIXME Make use of redraw or get rid of it completely */
 static int
-do_plist (PedDisk *cdisk) {
+main_plist(PedPartition **part, int key) {
+	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);
+		}
+		else if (key == ESC) {
+			key = 0;
+			getbool(N_("Are you sure you want to quit?"), &key);
+		}
+	}
+	else if (key == 'n') {
+		action_new(part);
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 'w') {
+		action_commit();
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 'f') {
+		action_mkfs(part);
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 'c') {
+		action_check(part);
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 'u') {
+		action_units();
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 's') {
+		action_rescue(part);
+		//redraw = 1;
+		key = 0;
+	}
+	else if (key == 'y') {
+		action_copy(part);
+		//redraw = 1;
+		key = 0;
+	}
+	else {
+		warning_waitkey("Unimplemented");	 /* TODO */
+		key = 0;
+	}
+	return key;
+}
+
+
+/* Okay, this is our partition list. If there is no pointer to partition given, ASSume main menu */
+static int
+do_plist (PedDisk *cdisk, PedPartition **part) {
 	int key = 0, i, redraw = 1, selnum = 0, start = 0;
 	const char* keys;
 	PedPartition *selected = NULL;
 	PedPartition *temp,*memp;
 	MenuOptions menu_opts = MENU_DEFAULT;
+	MenuItem *part_menu;
+	if (!part) 
+		part_menu = main_menu;
+	else {
+		part_menu = partselect_menu;
+		menu_opts |= MENU_TITLE;
+	}
 	do {
 		selected = ped_disk_next_partition(cdisk,selected);
 	} while (selected && selected->type & PED_PARTITION_METADATA);
 			plist_draw(cdisk,selected, selnum, &start);
 			redraw = 0;
 		}
-		if (selected->type & PED_PARTITION_EXTENDED)
+		if (part) {
+			if (selected->type & PED_PARTITION_EXTENDED || 
+			    selected->type & PED_PARTITION_FREESPACE)
+				keys = keys_cantselect;
+			else
+				keys = keys_partselect;
+		}
+		else if (selected->type & PED_PARTITION_EXTENDED)
 			keys = keys_ext;
 		else if (selected->type & PED_PARTITION_FREESPACE)
 			keys = keys_free;
 			}
 			key = 0;
 		}
-		else if (key == ESC || key == 'q') {
-			if (uiquery.need_commit) {
+		else {
+			if (part) {
+				if (key == ESC) {
+					return 0;
+				}
+				else if (key == 's') {
+					*part = selected;
+					return 1;
+				}
 				key = 0;
-				getbool(N_("Partition table has changed, are you sure you want to quit?"),
-				        &key);
+			} else {
+				key = main_plist(&selected, key);
+				redraw = 1;
 			}
-			else if (key == ESC) {
-				key = 0;
-				getbool(N_("Are you sure you want to quit?"), &key);
-			}
-		}
-		else if (key == 'n') {
-			action_new(&selected);
-			redraw = 1;
-			key = 0;
-		}
-		else if (key == 'w') {
-			action_commit();
-			redraw = 1;
-			key = 0;
-		}
-		else if (key == 'f') {
-			action_mkfs(&selected);
-			redraw = 1;
-			key = 0;
-		}
-		else if (key == 'c') {
-			action_check(&selected);
-			redraw = 1;
-			key = 0;
-		}
-		else if (key == 'u') {
-			action_units();
-			redraw = 1;
-			key = 0;
-		}
-		else {
-			print_warning("Unimplemented",0);	 /* TODO */
-			key = 0;
 		}
 		refresh();
 	}
+	return 1;
 	
 }
 
 init_disk() {
 	char buf[SMALLBUF];
 	int n;
-	static struct MenuItem custom_part[] = {
+	static MenuItem custom_part[] = {
 		{ 'c', N_("Choose"), N_("Prompt for device address") },
 		{ 'q', N_("Quit"), N_("Quit program") },
 		{ 0, NULL, NULL }
 	};
-	static struct MenuItem custom_label[] = {
+	static MenuItem custom_label[] = {
 		{ 'c', N_("Create"), N_("Create new partition table") },
 		{ 'q', N_("Quit"), N_("Quit program") },
 		{ 0, NULL, NULL }
 
 }
 
-static void
-print_info(void) {
-	
-}
 
 
 static void
 	int test = 0;
 
 	show_info();
-	do_plist(disk);
+	do_plist(disk,NULL);
 	endwin();
 }
 int
 static int
 get_device(const char* prompt, PedDevice** value, const UICalls *uiquery)
 {
-	char*		dev_name = *value ? (*value)->path : NULL;
+	char*		dev_name = *value ? strdup((*value)->path) : NULL;
 	PedDevice*	dev;
 	if (!uiquery->getdev) {
 		if (!uiquery->getstring (prompt, &dev_name, NULL, NULL, 1))
         PedFileSystem*  fs;
 	if (!part) {
 		if (!get_partition (_("Partition"),disk, &part, uiquery))
-			goto error;
+			return 0;
 	}
         if (!_partition_warn_busy (part))
-                goto error;
+                return 0;
 
         if (!ped_disk_check (disk))
-                goto error;
+                return 0;
 
         fs = ped_file_system_open (&part->geom);
         if (!fs)
-                goto error;
-        if (!ped_file_system_check (fs, uiquery->timer))
-                goto error_close_fs;
+                return 0;
+        if (!ped_file_system_check (fs, uiquery->timer)) {
+		ped_file_system_close (fs);
+		return 0;	
+	}
+
         ped_file_system_close (fs);
         return 1;
-error_close_fs:
-        ped_file_system_close (fs);
-error:
-        return 0;
 }
 
 /* Copy a partition.
    Writes partition table to disk */
 /* If warn is set to 1, warns the user TODO: get rid of warn */
 int
-do_cp (PedDisk* dst_disk, PedPartition* dst, int warn, UICalls *uiquery)
+do_cp (PedDisk* dst_disk, PedPartition* dst, UIOpts opts, UICalls *uiquery)
 {
         PedDisk*                src_disk = NULL;
-        PedDevice*              src_device;
         PedPartition*           src = NULL;
         PedFileSystem*          src_fs;
         PedFileSystem*          dst_fs;
         PedFileSystemType*      dst_fs_type;
-	if (warn)
+	if (opts & UI_WARN_COMMIT)
 		if (!ask_boolean_question 
 		(_("WARNING: This writes all data to disk automatically, continue?"),uiquery)) 
 			return 1;
 #define can_create_logical(disk) _can_create_logical(disk)
 
 extern int do_check (PedDisk*, PedPartition*, UICalls *);
-extern int do_cp (PedDisk*, PedPartition*, int warn, UICalls *);
+extern int do_cp (PedDisk*, PedPartition*, UIOpts, UICalls *);
 extern int do_mklabel (PedDevice*, PedDisk**, const PedDiskType*, UICalls *);
 extern int do_mkfs (PedDisk*, PedPartition*, const PedFileSystemType*, UIOpts, UICalls *);
 extern int do_mkpart (PedDisk*, PedSector start, PedSector end, PedPartitionType,
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.