1. Leslie P. Polzer
  2. fdisk

Commits

Milko Krachounov  committed 01e20a6

Move some functions that are not specific to cfdisk out of cfdisk.c. Fix some issues and implement some missing things. (fdisk@sv.gnu.org/fdisk--main--0--patch-32)
fdisk@sv.gnu.org/fdisk--main--0--patch-32
Keywords:

  • Participants
  • Parent commits 30ea15b
  • Branches default

Comments (0)

Files changed (5)

File src/cfdisk.c

View file
 #if ENABLE_NLS
 #  include <libintl.h>
 #  include <locale.h>
+/* TODO: Fix some localizing issues */
 #  define _(String) dgettext (PACKAGE, String)
 #  define P_(String) dgettext ("parted", String)
 #else
 
 int new_table = 0;
 int arrow_cursor = 0;
+int is_devicefile = 0;
 
 
 static void
 
 
 
-void
+static void
 set_status(const char *status, int warn_line) {
 	clear_status(warn_line);
 	/*attron(A_REVERSE);*/
 	/*attroff(A_REVERSE);*/
 }
 
-void
+static void
 print_warning(const char *status, int status_line) {
 	set_status(status,!status_line);
 	putchar(BELL);
 }
 
-void
+static void
 menu_title (const char *title) {
 	move(LINES - 2 - MENUSIZE, 0);
 	clrtoeol();
 }
 
 /* Menu drawing function */
-void
+static void
 menu_draw (const 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);
 	return key;
 }
 
-
+/* Lines at the top of the string list drawer */
+#define SLD_HEAD 5
 /* String list choice */
 /* The last two parameters specify the number of the selected element and the first element displayed 
    last time. If opts & 1, we assume it is a fullscreen text, not choice*/
 static void
 strlist_draw (const char *prompt, const StrList *strlist, int opts, const StrList* selected, 
               int selnum, int *start) {
-	/*char buf[SMALLBUF]; *//* FIXME: Not needed */
 	char *temp;
 	int n,x,y,i;
 	const StrList *current;
 
 	if (opts & 1) {
-		/* 5 are the additional lines, TODO: make this a #define */
-		*start = selnum - (LINES - 2 - 5);
+		*start = selnum - (LINES - 2 - SLD_HEAD);
 		*start = MAX(0,*start);
 		y = 0;
 		n = LINES - 2;
 		y = INFOSIZE;
 		if (selnum - *start < 0)
 			*start = selnum;
-		else if (selnum - *start >= n - INFOSIZE - 4)
-			*start = selnum - n + INFOSIZE + 5;
+		else if (selnum - *start > n - INFOSIZE - SLD_HEAD)
+			*start = selnum - n + INFOSIZE + SLD_HEAD;
 
 	}
 	move(y++,0); clrtoeol();
 	move(y,0); clrtoeol(); mvaddstr(y++,5,prompt);
-	/* FIXME: Using buf here not needed. This appears another time in source. */
-	mvaddch(y,0,' ');//' 'buf[0] = ' ';
+	mvaddch(y,0,' ');
 	for (x = 1; x < COLS-1; x++) {
-		mvaddch(y,x,'-'); //buf[i] = '-';
+		mvaddch(y,x,'-');
         }
 	mvaddch(y++,x,' ');
-	//if (i < SMALLBUF) buf[i++] = ' ';
-	//if (i < SMALLBUF) buf[i] = '\0';
-	//mvaddstr(y++,0,buf);
 	move(y++,0); clrtoeol();
 	x = (opts & 1 ? 1 : 7);
 	for (current = strlist, i = 0; current && y < n; current = current->next, i++) {
 do_strlist (const char *prompt, const StrList *strlist, int opts) {
 	const StrList *selected = strlist, *temp;
 	int redraw = 1, key = 0, done = 0, start = 0, selnum = 0;
-	const char* end_warning = opts & 1 ? _("No more text") : _("No more choices");
+	const char* end_warning = opts & 1 ? 
+	                              _("No more text") : _("No more choices");
 	if (opts & 1) {
 		for (selnum = 0, selected = strlist; 
-		     selnum < LINES-2-5 && selected->next;
+		     selnum < LINES-2-SLD_HEAD && selected->next;
 		     selnum++, selected = selected->next);
 	}
 	while (!done) {
 			key = getch();
 			if (key == '[' || key == 'O') {
 			key = getch();
-				if (key == 'B' && !(opts & 2)) { /* That's down arrow */
+				if (key == 'B' && !(opts & 2)) { /*Down arrow*/
 					if (!selected->next)
 						print_warning(end_warning,0);
 					else {
 						redraw = 1;
 					}
 				}
-				else if (key == 'A' && !(opts & 2)) { /* That's up arrow */
+				else
+				if (key == 'A' && !(opts & 2)) { /*Up arrow*/
 					if (strlist == selected || 
-					    ((opts & 1) && selnum <= LINES-2-5))
+					    ((opts & 1) && selnum <= LINES-2-SLD_HEAD))
 						print_warning(end_warning,0);
 					else {
 					/* FIXME: Edit strlist and make this faster */
 	}
 	if (*value) ped_free (*value);
 	*value = strdup(buf);
-	//n = strlen(buf);
-	//*value = (char *)calloc(n,sizeof(char));
-	//strncpy(*value,buf,n);
 	return 1;
 	
 }
 	return do_plist(disk,value,0,PED_PARTITION_EXTENDED | PED_PARTITION_FREESPACE);
 }
 
+static int
+getpartpos (const char* prompt, const void* context, const char *possibilities)
+{
+	return do_menu((MenuItem*) context, 11, MENU_BUTTON | MENU_TITLE,
+	               possibilities, NULL);
+}
 
 static PedExceptionOption
 exception_handler (PedException* ex) {
 	for (i = 0; ex_keys[i].key; i++)
 		if (ex->options & ex_keys[i].option) {
 #if 0
-			if (k >= TINYBUF) break; /* NOTE: This is not needed now, but have in mind */
+			/* NOTE: This is not needed now, but have in mind */
+			if (k >= TINYBUF) break; 
 #endif
 			keys[k++] = ex_keys[i].key;
 		}
 	uiquery.getbool = getbool;
 	uiquery.getstring = getstring;
 	uiquery.getpart = getpart;
+	uiquery.getpartpos = getpartpos;
 	uiquery.need_commit = 0;
 	uiquery.timer = ped_timer_new (_timer_handler, &timer_context);
 	ped_exception_set_handler(exception_handler);
 	return temp_a;
 }
 
-/* TODO: Move this to common? */
-/* TODO: This is not quite OK at the moment... */
-/* We ask the user where to put the partition in a region. Used for creating and resizing partitions */
-/* first and last mark the margins of the region, start and end mark the current values */
-static int
-_query_part_position(const MenuItem* menu, PedSector *start, PedSector *end, 
-		     PedSector first, PedSector last, PedConstraint *constraint, UIOpts *opts) {
-	
-	PedSector length = *end-*start+1, min_len = 0, max_len = dev->length;
-	int key,i,done;
-	char *temp,*temp2,*def_str, keys[6], buf[SMALLBUF];
-	i = 0;
-	/* If we have a constraint, check whether we can move the partition start */
-	if (constraint && (constraint->start_align->grain_size == 0 || constraint->start_range->length == 1))
-		key = 's';
-	else {
-		/* If there the first possible sector is not the start of the selected partition,
-			we need one choice in the menu to make the start fixed and one to move it back.
-			When it is, 'b' and 's' do the same. We ditch 'b' for more friendly resize menu,
-			action_new should use 's' as it doesn't matter there. 
-			FIXME: I wrote this fragment better, but ruined it. Now I'm too lazy to fix it */
-		if (first < *start) keys[i++] = 'b';
-		keys[i++] = 's'; keys[i++] = 'e'; keys[i++] = 'c';
-		keys [i++] = ESC;
-		keys [i] = '\0';
-		/* NOTE: Run menu_title before running this function */
-		//menu_title(_("Where do you want to put the partition"));
-		key = do_menu(menu, 11, MENU_BUTTON | MENU_TITLE, keys, NULL);
-	}
-	if (key == ESC)
-		return 0;
-	else {
-		if (key == 'c') {
-			*opts |= UI_CUSTOM_VALUES;
-		} else {
-			*opts &= ~UI_CUSTOM_VALUES;
-			if (key == 's')
-				max_len = last-*start+1;
-			else
-				max_len = last-first+1;
-			if (constraint) {
-				max_len = MIN(constraint->max_size,max_len);
-				min_len = constraint->min_size;
-			}
-			done = 0;
-			while (!done) {
-				/* Put the max and min size on the prompt */
-				temp = ped_unit_format(dev,min_len);
-				temp2 = ped_unit_format(dev,max_len);
-				if (temp && temp2) {
-					snprintf(buf,SMALLBUF,_("Size (min %s, max %s)"),
-						temp, temp2);
-				} else {
-					strncpy(buf,_("Size"),SMALLBUF);
-				}
-				if (temp) ped_free(temp);
-				if (temp2) ped_free(temp2);
-				def_str = ped_unit_format(dev,length);
-				if (def_str) temp = strdup(def_str);
-				if (!read_char(buf, &temp)) {
-					if (temp) ped_free(temp);
-					if (def_str) ped_free(def_str);
-					return 0;
-				}
-	
-				done = 1;
-				/* Get the new size only if the user modified it */
-				if(strcmp(temp,def_str)) {
-					if (!ped_unit_parse(temp,dev,&length,NULL)) {
-						warning_waitkey(N_("This is an invalid partition size"));
-						done = 0;
-					}
-					else if (length > max_len) {
-						length = max_len;
-					} else if (length < min_len) {
-						length = min_len;
-					}
-				}
-				if (temp) ped_free(temp);
-				if (def_str) ped_free(def_str);
-			}
-			if (key == 'b') {
-				*start = first;
-				*end = first+length-1;
-			}
-			else if (key == 'e') {
-				*end = last;
-				*start = last-length+1;
-			}
-			else if (key == 's') {
-				*end = *start+length-1;
-			}
-		}
-	}
-	return 1;
-	
-}
-/* TODO: Move to common? */
-/* This function returns the closest possible start and end for a partition
-   in the region fist-last */
-static int
-_fix_part_position(PedSector *start, PedSector *end, PedSector first,
-                   PedSector last)
-{
-	/* Current geometry */
-	PedGeometry *geom = ped_geometry_new (dev,*start,*end-*start+1);
-	if (!geom) return 0;
-	/* Possible range */
-	PedGeometry *range = ped_geometry_new (dev, first, last-first+1);
-	if (!range) {
-		ped_geometry_destroy(geom);
-		return 0;
-	}
-	PedConstraint *constraint = constraint_intersect_and_destroy(
-			constraint_from_start_end (dev, range, range),
-			ped_device_get_constraint (dev));
-
-	PedGeometry *new_geom = ped_constraint_solve_nearest(constraint, geom);
-
-	if (new_geom) {
-		if (*start != new_geom->start || *end != new_geom->end) {
-			/*char buf[SMALLBUF];
-			snprintf(buf,SMALLBUF,_("We changed the partition from %llds-%llds to %llds-%llds"),
-				*start,*end,new_geom->start,new_geom->end);
-			warning_waitkey(buf);*/
-			*start = new_geom->start;
-			*end = new_geom->end;
-			ped_geometry_destroy(new_geom);
-		}
-		return 1;
-	} 
-
-	return 0;
-
-}
-
-
-
 /* Emergency function. If some copy, move or resize fail, reread the disk from the device
    They commited it before failing, anyway. It is a bit like a hack, I might make the functions
    make it themselves. I actually did, but I had a little trouble with the UI, so for now it is this way
 
 	start = (*part)->geom.start;
 	end = (*part)->geom.end;
-	menu_title(_("Where do you want to put the partition"));
-	if(!_query_part_position(part_position,&start,&end,start,end,NULL,&opts))
+	if(!query_part_position(_("Where do you want to put the partition"),
+	                        part_position,&start,&end,start,end,dev,
+	                        NULL,&opts))
 		return 0;
 
 	if (!do_mkpart(disk,start,end,type,NULL,part,opts)) {
 	if ((*part)->next && (*part)->next->type & PED_PARTITION_FREESPACE)
 		last = (*part)->next->geom.end;
 	else last = end;
-
-	menu_title(_("Where to place the resized partition"));
-	if(!_query_part_position(part_position,&start,&end,first,last,
-	   constraint,&opts) || !_fix_part_position(&start,&end,first,last)) {
+	if(!query_part_position(_("Where to place the resized partition"),
+	                        part_position,&start,&end,first,last,dev,
+	                        constraint,&opts)) {
 		if (constraint) ped_constraint_destroy (constraint);
 		return 0;
 	}
 	length = MIN(length,(*part)->geom.length);
 	length = MAX(length,constraint->min_size);
 	end = start+length-1;
-	if(!_query_part_position(part_position,&start,&end,start,dst->geom.end,constraint,&opts)) {
+	if(!query_part_position(_("Where do you want to move the partition"),
+	                        part_position,&start,&end,start,dst->geom.end,
+	                        dev,constraint,&opts)) {
 		ped_constraint_destroy (constraint);
 		return 0;
 	}
 					}
 				}
 				else if (key == 'A') { /* That's up arrow */
-					/* You are not expected to understand this. */
+					/* Better try to solve a 5D rubic *
+					 * cube, than to figure this out. */
 					temp_a = 0;
 					temp_b = 0;
 					do { 
 	StrList *info = NULL;
 	char buf[SMALLBUF];
 	const char *temp;
-	int i;
+	int n;
 
 	unsigned int system_type;
 	int system_type_size;
 
 
-	/* TODO: This now displays bullshit */
-	snprintf(buf,SMALLBUF,"%30s: %s%d", _("Possible partition device"), dev->path, (*part)->num);
-	info = str_list_append(info,buf);
+	/* TODO: I did like it is done in Linux cfdisk. 
+	         This won't be always correct */
+	n = strlen(dev->path);
+	if (!is_devicefile) {
+		snprintf(buf,SMALLBUF,
+			isdigit(dev->path[n-1]) ? "%30s: %sp%d" : "%30s: %s%d",
+			_("Possible partition device"), dev->path, (*part)->num);
+		info = str_list_append(info,buf);
+	}
 
 	if ((*part)->type & PED_PARTITION_LOGICAL)
 		temp = _("Logical");
 			key = 0;
 			break;
 		default:
-			warning_waitkey("Unimplemented");	 /* TODO */
+			/* NOTE: I think this can't be reached */
+			warning_waitkey("Unimplemented");
 			key = 0;
 	}
 	return key;
 		}
 		else do_quit(0,NULL);
 	}
+	is_devicefile = !is_blockdev(dev->path);
 	if (!new_table) {
 		ped_exception_fetch_all ();
 		disk = ped_disk_new(dev);
 	info_size = calloc(n,sizeof(char));
 	strncpy(info_size,buf,n);
 
-	n = strlen(dev->model);
-	info_model = calloc(n,sizeof(char));
-	strncpy(info_model,dev->model,n);
+	/* FIXME: Isn't changing the pointer enough, why we cpy? */
+	if (is_devicefile) 
+		info_model = _("Device file");
+	else {
+		n = strlen(dev->model);
+		info_model = calloc(n,sizeof(char));
+		strncpy(info_model,dev->model,n);
+	}
 	
 	snprintf(buf,SMALLBUF,"%lldB/%lldB\n",dev->sector_size, dev->phys_sector_size);
 	n = strnlen(buf);

File src/common.c

View file
         return result;
 }
 
+/* This function returns the closest possible start and end for a partition
+   in the region first-last */
+int
+fix_part_position(PedDevice *dev, PedSector *start, PedSector *end,
+                  PedSector first, PedSector last)
+{
+	/* Current geometry */
+	PedGeometry *geom = ped_geometry_new (dev,*start,*end-*start+1);
+	if (!geom) return 0;
+	/* Possible range */
+	PedGeometry *range = ped_geometry_new (dev, first, last-first+1);
+	if (!range) {
+		ped_geometry_destroy(geom);
+		return 0;
+	}
+	PedConstraint *constraint = constraint_intersect_and_destroy(
+			constraint_from_start_end (dev, range, range),
+			ped_device_get_constraint (dev));
 
+	PedGeometry *new_geom = ped_constraint_solve_nearest(constraint, geom);
+
+	if (new_geom) {
+		if (*start != new_geom->start || *end != new_geom->end) {
+			*start = new_geom->start;
+			*end = new_geom->end;
+			ped_geometry_destroy(new_geom);
+		}
+		return 1;
+	} 
+
+	return 0;
+
+}
+
+#define ESC	'\033'	/* ^[ */
+/* TODO: This is not quite OK at the moment... */
+/* We ask the user where to put the partition in a region. Used for creating and resizing partitions */
+/* first and last mark the margins of the region, start and end mark the current values */
+int
+query_part_position(const char* prompt, const void* context, PedSector *start,
+                    PedSector *end,  PedSector first, PedSector last,
+                    PedDevice *dev, PedConstraint *constraint, UIOpts *opts) {
+	
+	PedSector length = *end-*start+1, min_len = 0, max_len = dev->length;
+	int where,i,done;
+	char *temp,*temp2,*def_str, possibilities[6], buf[SMALLBUF];
+	i = 0;
+	/* If we have a constraint, check whether we can move the partition start */
+	if (constraint && (constraint->start_align->grain_size == 0 || 
+	                   constraint->start_range->length == 1))
+		where = 's';
+	else {
+		/* If there the first possible sector is not the start of the selected partition,
+			we need one choice in the menu to make the start fixed and one to move it back.
+			When it is, 'b' and 's' do the same. We ditch 'b' for more friendly resize menu,
+			action_new should use 's' as it doesn't matter there. 
+			FIXME: I wrote this fragment better, but ruined it. Now I'm too lazy to fix it */
+		if (first < *start) possibilities[i++] = 'b';
+		possibilities[i++] = 's';
+		possibilities[i++] = 'e';
+		possibilities[i++] = 'c';
+		possibilities [i++] = ESC;
+		possibilities [i] = '\0';
+		where = uiquery->getpartpos(prompt, context, possibilities);
+	}
+	if (where == ESC)
+		return 0;
+	else {
+		if (where == 'c') {
+			*opts |= UI_CUSTOM_VALUES;
+		} else {
+			*opts &= ~UI_CUSTOM_VALUES;
+			if (where == 's')
+				max_len = last-*start+1;
+			else
+				max_len = last-first+1;
+			if (constraint) {
+				if (constraint->max_size < max_len)
+					max_len = constraint->max_size;
+				min_len = constraint->min_size;
+			}
+			done = 0;
+			while (!done) {
+				/* Put the max and min size on the prompt */
+				temp = ped_unit_format(dev,min_len);
+				temp2 = ped_unit_format(dev,max_len);
+				if (temp && temp2) {
+					snprintf(buf,SMALLBUF,_("Size (min %s, max %s)"),
+						temp, temp2);
+				} else {
+					strncpy(buf,_("Size"),SMALLBUF);
+				}
+				if (temp) ped_free(temp);
+				if (temp2) ped_free(temp2);
+				def_str = ped_unit_format(dev,length);
+				if (def_str) temp = strdup(def_str);
+				if (!uiquery->getstring(buf, &temp, NULL, NULL, 1)) {
+					if (temp) ped_free(temp);
+					if (def_str) ped_free(def_str);
+					return 0;
+				}
+	
+				done = 1;
+				/* Get the new size only if the user modified it */
+				if(strcmp(temp,def_str)) {
+					if (!ped_unit_parse(temp,dev,&length,NULL)) {
+						done = !ped_exception_throw(
+							PED_EXCEPTION_ERROR,
+							PED_EXCEPTION_RETRY_CANCEL,
+							"%s is an invalid partition size",
+							temp);
+						if (done)
+							return 0;
+					}
+					else if (length > max_len) {
+						length = max_len;
+					} else if (length < min_len) {
+						length = min_len;
+					}
+				}
+				if (temp) ped_free(temp);
+				if (def_str) ped_free(def_str);
+			}
+			if (where == 'b') {
+				*start = first;
+				*end = first+length-1;
+			}
+			else if (where == 'e') {
+				*end = last;
+				*start = last-length+1;
+			}
+			else if (where == 's') {
+				*end = *start+length-1;
+			}
+		}
+	}
+	return 1;
+	
+}
 
 static int
 get_device(const char* prompt, PedDevice** value)

File src/common.h

View file
 	int (*getpart)(const char* prompt, PedDisk**, PedPartition** value);
 	int (*getdisktype)(const char* prompt, PedDiskType** value);
 	int (*getfstype)(const char* prompt, PedFileSystemType** value);
+	int (*getpartpos)(const char* prompt, const void* context, 
+	                   const char *possibilities);
 	PedTimer* timer;
 	int need_commit;
 };
 				PedGeometry* range_end);
 extern PedConstraint*
 constraint_intersect_and_destroy (PedConstraint* a, PedConstraint* b);
+/* This function returns the closest possible start and end for a partition
+   in the region first-last */
+extern int fix_part_position(PedDevice *dev, PedSector *start, PedSector *end,
+                             PedSector first, PedSector last);
 
+/* Choose the partition position */
+extern int
+query_part_position(const char* prompt, const void* context, PedSector *start,
+                    PedSector *end,  PedSector first, PedSector last,
+                    PedDevice *dev, PedConstraint *constraint, UIOpts *opts);
 #endif

File src/hacks.c

View file
 #include "../config.h"
 #include <string.h>
 #include <stdint.h>
+#include <sys/stat.h>
 #include "hacks.h"
 
 #define MSDOS_HACK 1
 #define PC98_HACK 0
 #define AMIGA_HACK 0
 
+/* Check if it is a block device. Returns -1 if not found. */
+int is_blockdev(const char *file) {
+	struct stat file_stat;
+	if (stat(file,&file_stat) < 0)
+		return -1;
+	if(S_ISBLK(file_stat.st_mode))
+		return 1;
+	else
+		return 0;
+}
+
 /* We need a function to get disk type-specific info about filesystem */
 /* TODO: Decide if we actually need all these... I think we should leave them, at least for the 
    msdos partition type. */

File src/hacks.h

View file
 #define HACKS_H_INCLUDED
 #include <parted/parted.h>
 
+extern int is_blockdev(const char *file);
 extern const char* get_disk_specific_system_name (PedPartition*);
 extern unsigned int get_disk_specific_system_type (PedPartition *part, int *size);
 #endif