Anonymous avatar Anonymous committed 8d0a1a9

Add bsd and sun system types. Make fdisk use them. Implement display of system types in columns. Implement experimental function for fixing the partition order in common.c (needed for lfdisk). Fix some bugs in cfdisk.c and common.c. (fdisk@sv.gnu.org/fdisk--main--0--patch-43)
fdisk@sv.gnu.org/fdisk--main--0--patch-43
Keywords:

Comments (0)

Files changed (7)

 		y++;
 	}
 	/* We clear the next line. No need to clean all lines, unless we implement page up and down */
-	if (y < n) {
+	while (y < n) {
 		move(y,0); clrtoeol();
+		y++;
 	} 
 }
 static void show_info();
 		}
 	}
 	if (!perform_mkfs (disk, *part, type, UI_WARN_COMMIT)) {
-		warning_waitkey(N_("The filesystem was created successfully"));
+		warning_waitkey(N_("The filesystem was not created successfully"));
 		return 0;
 	}
-	notice_waitkey(N_("The filesystem was not created successfully."));
+	notice_waitkey(N_("The filesystem was created successfully."));
 	return 1;
 }
 
 
 static int
 do_units () {
+	/* TODO: The shortcuts are not very cool */
 	static MenuItem units[] = {
 		{ '1' , N_("Sectors"), N_("Show the sizes in sectors") },
 		{ '2' , N_("Bytes"), N_("Show the sizes in bytes") },
 	/* TODO: I did like it is done in Linux cfdisk. 
 	         This won't be always correct */
 	n = strlen(dev->path);
-	if (!is_devicefile) {
+	if (!is_devicefile && !((*part)->type & PED_PARTITION_FREESPACE)) {
 		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)
+	if ((*part)->type & PED_PARTITION_FREESPACE) {
+		if ((*part)->type & PED_PARTITION_LOGICAL)
+			temp = _("Free space inside an extended partition");
+		else
+			temp = _("Free space");
+	}
+	else if ((*part)->type & PED_PARTITION_LOGICAL)
 		temp = _("Logical");
 	else if ((*part)->type & PED_PARTITION_EXTENDED)
 		temp = _("Extended");
 	info = str_list_append(info,"");
 
 	/* Filesystem info */
-	if ((*part)->fs_type) {
-		snprintf(buf,SMALLBUF,"%30s: %s", _("Filesystem type"), (*part)->fs_type->name);
-		info = str_list_append(info,buf);
+	if (!((*part)->type & PED_PARTITION_FREESPACE)) {
+		if ((*part)->fs_type) {
+			snprintf(buf,SMALLBUF,"%30s: %s", _("Filesystem type"), (*part)->fs_type->name);
+			info = str_list_append(info,buf);
+		}
+	
+		system_type = get_disk_specific_system_type(*part,&system_type_size);
+		if (system_type_size) {
+			system_type_size *= 2;
+			snprintf(buf,SMALLBUF,"%30s: 0x%0*x", _("System type"), system_type_size, system_type);
+			info = str_list_append(info,buf);
+		}
+		temp = get_disk_specific_system_name(*part);
+		if (temp) {
+			snprintf(buf,SMALLBUF,"%30s: %s", _("System type name"), temp);
+			info = str_list_append(info,buf);
+		}
 	}
-
-	system_type = get_disk_specific_system_type(*part,&system_type_size);
-	if (system_type_size) {
-		system_type_size *= 2;
-		snprintf(buf,SMALLBUF,"%30s: 0x%0*x", _("System type"), system_type_size, system_type);
-		info = str_list_append(info,buf);
-	}
-	temp = get_disk_specific_system_name(*part);
-	if (temp) {
-		snprintf(buf,SMALLBUF,"%30s: %s", _("System type name"), temp);
-		info = str_list_append(info,buf);
-	}
-
 	info = str_list_append(info,"");
 	/* Position in sectors */
 	snprintf(buf,SMALLBUF,"%30s: %llds-%llds", _("Position"), 
 	info = str_list_append(info,"");
 	
 	/* Flags */
-	snprintf(buf,SMALLBUF,"%30s: %s", _("Flags"), partition_print_flags(*part));
-	info = str_list_append(info,buf);
-	info = str_list_append(info,"");
+	if (!((*part)->type & PED_PARTITION_FREESPACE)) {
+		snprintf(buf,SMALLBUF,"%30s: %s", _("Flags"), partition_print_flags(*part));
+		info = str_list_append(info,buf);
+		info = str_list_append(info,"");
+	}
+
 	do_strlist(_("Partition info"),info,3);
 	str_list_destroy(info);
 	
 };
 
 const char keys_ext[] = { 'm','d','u','w','q','i','h','r','x','z',UP_KEY,DOWN_KEY, '\0' };
-const char keys_free[] = { 'n','s','u','w','q','h',UP_KEY,DOWN_KEY, '\0' };
+const char keys_free[] = { 'n','s','u','w','q','h','i',UP_KEY,DOWN_KEY, '\0' };
 const char keys_part[] = { 'b','f','c','m','y','r','o','d','t','u','w','q','i','h',UP_KEY,DOWN_KEY, '\0' };
 /*bfcayrodtuwqph*/
 
 						done = !ped_exception_throw(
 							PED_EXCEPTION_ERROR,
 							PED_EXCEPTION_RETRY_CANCEL,
-							"%s is an invalid partition size",
+							_("%s is an invalid partition size"),
 							temp);
 						if (done)
 							return 0;
 	}
 
         if (!disk)
-                goto error;
+                return 0;
 	if (!part) {
 		if (!get_partition (_("Partition"),disk, &part))
-			goto error;
+			return 0;
 	}
         if (!_partition_warn_busy (part))
-                goto error;
+                return 0;
 	if (!type) {
 		type = ped_file_system_type_get ("ext2");
         	if (!get_fs_type (_("File system"), &type, 1))
-	                goto error;
+	                return 0;
 	}
 	/* We check whether we can create this partition here */
 	constraint = ped_file_system_get_create_constraint(type,disk->dev);
 
         fs = ped_file_system_create (&part->geom, type, uiquery->timer);
         if (!fs)
-                goto error;
+                return 0;
         ped_file_system_close (fs);
 
         if (!ped_partition_set_system (part, type))
-                goto error;
+                return 0;
         if (ped_partition_is_flag_available (part, PED_PARTITION_LBA))
                 ped_partition_set_flag (part, PED_PARTITION_LBA, 1);
         if (!ped_disk_commit (disk)) {
 		//if (uiquery->need_commit) uiquery->need_commit = -1;
-                goto error;
+               return 0;
 	}
 	uiquery->need_commit = 0;
         return 1;
 
 
-error:
-        return 0;
 }
 
 /* The parameter custom is 1, then the user is asked about the start and end sector *
 		if (!get_position(pos, disk, opts & UI_CUSTOM_VALUES))
 			goto error;
 	}
-	/*ped_exception_throw(PED_EXCEPTION_INFORMATION,
-			PED_EXCEPTION_OK,
-			"Create %llds-%llds (%llds-%llds)-(%llds-%llds)",
-			pos->start.sector, pos->end.sector,
-			pos->start.range->start, pos->start.range->end,
-			pos->end.range->start, pos->end.range->end);
-	*/      
 
         /* processing starts here */
         part = ped_partition_new (disk, part_type, fs_type,
 	else return 0;
 }
 
+/* Experimental fixing of the partition order */
+
+/* We will copy this part of the DosPartitionData */
+struct DosPDCopyMem {
+	unsigned char	system;
+	int		boot;
+	int		hidden;
+	int		raid;
+	int		lvm;
+	int		lba;
+	int		palo;
+	int		prep;
+};
+#define DOS_DATA_SIZE sizeof(struct DosPDCopyMem)
+
+#define DO_NOT_SAVE (PED_PARTITION_FREESPACE | PED_PARTITION_METADATA)
+
+struct DOSGeomList {
+	PedGeometry geom;
+	void *part_data;
+
+	/* These are not necessary */
+	const PedFileSystemType * fs_type;
+	PedPartitionType type;
+
+	struct DOSGeomList *next;
+};
+
+int
+_fix_order_add_part (PedDisk *disk, struct DOSGeomList *data) {
+	int success;
+	PedConstraint *constraint;
+	PedGeometry *range_start, *range_end;
+	PedPartition *part;
+	part = ped_partition_new (disk, data->type, data->fs_type,
+					data->geom.start, data->geom.end);
+
+	range_start = ped_geometry_new (disk->dev,data->geom.start, 1);
+	range_end = ped_geometry_new (disk->dev,data->geom.end, 1); 
+	constraint = constraint_from_start_end(disk->dev,
+						range_start,range_end);
+	memcpy(part->disk_specific, data->part_data, DOS_DATA_SIZE); 
+	success = ped_disk_add_partition (disk, part, constraint);
+
+	if (constraint) ped_constraint_destroy(constraint);
+	if (range_start) ped_geometry_destroy(range_start);
+	if (range_end) ped_geometry_destroy(range_end);
+	if (!success) ped_partition_destroy(part);
+
+	return success;
+}
+
+int
+fix_partition_order (PedDisk *disk)
+{
+	if (strcmp(disk->type->name, "msdos")) {
+		ped_exception_throw(PED_EXCEPTION_NO_FEATURE,
+		                    PED_EXCEPTION_CANCEL,
+		                    _("Fixing partition order on %s partition "
+		                      "label type not implemented."), 
+		                    disk->type->name);
+		return 0;
+	}
+
+
+	PedPartition *walk;
+	int i = 0, j = 4;
+
+	/* We check that order of the partitions is really wrong */
+	for (walk = ped_disk_next_partition(disk,NULL); walk;
+	     walk = ped_disk_next_partition(disk,walk)) {
+		if (walk->type & DO_NOT_SAVE)
+			continue;
+		if (walk->type & PED_PARTITION_LOGICAL) {
+			j++;
+			if (walk->num != j) {
+				j = -1;
+				break;
+			}
+		}
+		else {
+			i++;
+			if (walk->num != i) {
+				i = -1;
+				break;
+			}
+		}
+	}	
+	if (i != -1 && j != -1) 
+		return 1;
+
+	/* We make sure that there are no mounted partitions */
+	if (!_disk_warn_busy (disk))
+		return 0;
+
+	/* We will issue warning to the user for now */
+	if (PED_EXCEPTION_CANCEL == ped_exception_throw(PED_EXCEPTION_WARNING,
+							PED_EXCEPTION_IGNORE_CANCEL,
+							"Fixing partition order "
+							"is experimental. Use "
+							"at your own risk."))
+		return 0;
+
+	struct DOSGeomList *partitions = NULL;
+	struct DOSGeomList *pdata = NULL;
+	struct DOSGeomList **ptr = &partitions;
+
+	
+	
+
+	/* We save the primary partitions */
+	for (walk = ped_disk_next_partition(disk,NULL); walk;
+	     walk = ped_disk_next_partition(disk,walk)) {
+		if (walk->type & DO_NOT_SAVE)
+			continue;
+
+		/* We save the partition in the list */
+		*ptr = malloc(sizeof(struct DOSGeomList));
+		(*ptr)->geom = walk->geom;
+		(*ptr)->part_data = malloc(DOS_DATA_SIZE);
+		memcpy((*ptr)->part_data, walk->disk_specific, DOS_DATA_SIZE);
+		(*ptr)->fs_type = walk->fs_type;
+		(*ptr)->type = walk->type;
+		(*ptr)->next = NULL;
+		ptr = &((*ptr)->next);
+
+	}
+
+	/* We delete the partitions */
+	for (i = 1; i <= 4; i++) {
+		if (walk = ped_disk_get_partition(disk,i))
+			ped_disk_delete_partition (disk, walk);
+	}
+
+	/* FIXME: We assume this doesn't fail. Fix ! */
+	/* We recreate the partitions again */
+	pdata = partitions;
+	while (pdata) {
+		_fix_order_add_part(disk, pdata);
+		pdata = pdata->next;
+	}
+	
+	/* We clear the saved data */
+	pdata = partitions;
+	while (pdata) {
+		struct DOSGeomList *next = pdata->next;
+		free(pdata->part_data);
+		free(pdata);
+		pdata = next;
+	}
+		
+	/* We're done */
+	uiquery->need_commit = 1;
+	return 1;
+}
 
 char*
 partition_print_flags (PedPartition* part)
 extern int perform_set (PedDisk*, PedPartition*, PedPartitionFlag, UIOpts);
 extern int perform_commit (PedDisk*, UIOpts);
 extern int perform_maximize (PedDisk*, PedPartition*);
+extern int fix_partition_order (PedDisk*);
+
 
 /* Additional functions */
 extern char* partition_print_flags (PedPartition*);
                         int mkfs);
 extern int get_part_flag (const char* prompt, PedPartition*, PedPartitionFlag*);
 
+
 #endif
 							destroy disk. */ 
 	const PedDiskType*	type = ped_disk_type_get ("sun");
 
-	ped_exception_fetch_all ();
-
-	return perform_mklabel(dev,disk,type);
+		return perform_mklabel(dev,disk,type);
 }
 
 static int
 							destroy disk. */ 
 	const PedDiskType*	type = ped_disk_probe (dev);
 
-	ped_exception_fetch_all ();
 
 	return perform_mklabel(dev,disk,type);
 }
 	return status;
 }
 
-/* TODO: This is a temporary solution, we should turn it around... */
 static int
-do_list_msdos_systypes (PedDisk** disk)
+do_list_systypes (PedDisk** disk)
 {
-	int i,j = 0;
-	for (i = 0; msdos_systypes[i].name; i++) {
-		printf("%2x  %-16s%s", (unsigned int) msdos_systypes[i].type,
-		       msdos_systypes[i].name, j == 3 ? "\n" : " ");
-		j = (j + 1) % 4;
+	SysType* types = get_disklabel_system_types((*disk)->type);
+	if (!types) {
+		printf(_("System types for this disk label type are not "
+		         "available.\n"));
+		return 1;
 	}
+	int count, per_row = 4, per_col, i, j = 0;
+
+	/* We calculate the system types count */
+	for (count = 0; types[count].name; count++);
+
+	/* We calculate the number of columns for the currect screen size */
+	per_row = fdisk_screen_width()/20;
+	/* We calculate the maximum number of elements per column */
+	per_col = count/per_row + 1;
+
+	/* We arrange the types in columns */
+	for (i = 0; i <  per_col; i++) {
+		for (j = 0; j < per_row; j++) {
+			if (i+j*per_col >= count)
+				break;
+			printf("%2x  %-15.15s ",
+				(unsigned int) types[i+j*per_col].type,
+				_(types[i+j*per_col].name));
+		}
+		printf("\n");
+	}
+
 	return 1;
 }
 
 	PedPartition *part = NULL;
 	char *input = NULL;
 	const char *type_name = NULL;
-
+	SysType *types = get_disklabel_system_types((*disk)->type);
+	if (!types) {
+		if (!command_line_prompt_boolean_question 
+			(_("WARNING: System types for this disk label type "
+			    "seem unavailable, continue?"))) 
+			return 0;
+	}
 	const char prompt[] = "Hex code (type L to list codes)";
 
 	if(!get_partition(_("Partition"), *disk, &part) || !part)
 			return 0;
 		if (!strcmp(input,"L")) {
 			free(input);
-			do_list_msdos_systypes(disk);
+			do_list_systypes(disk);
 		}
 		else
 			break;
 		return 0;
 	}
 	set_disk_specific_system_type(part,type);
-	for (i = 0; msdos_systypes[i].name; i++) {
-		if (msdos_systypes[i].type == type)
-			type_name = _(msdos_systypes[i].name);
-	}
+	if (types)
+		for (i = 0; types[i].name; i++) {
+			if (types[i].type == type)
+				type_name = _(types[i].name);
+		}
 	if (!type_name)
 		type_name = _("Unknown");
 	
 	return 1;
 }
 
+static int
+do_fix_partition_order (PedDisk **disk)
+{
+	fix_partition_order(*disk);
+}
+
 static void
 _init_messages ()
 {
 _(" d   delete a partition"),
 NULL), NULL, 1));
 
+/* TODO: Move */
+	fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
+		str_list_create_unique ("f", _("f"), NULL),
+		do_fix_partition_order,
+		str_list_create (
+_(" f   fix partition order"),
+NULL), NULL, 1));
+/* End TODO */
 
 	fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
 		str_list_create_unique ("l", _("l"), NULL),
-		do_list_msdos_systypes,
+		do_list_systypes,
 		str_list_create (
 _(" l   list known partition types"),
 NULL), NULL, 1));
  * not be the greatest idea. Rename to something.
  */
 
+
+/* TODO: This might go into libparted */
+
 /* Check if it is a block device. Returns -1 if not found. */
 int is_blockdev(const char *file) {
 	struct stat file_stat;
 } AmigaPartitionData;
 #endif
 
+
+SysType *
+get_disklabel_system_types (const PedDiskType *type) {
+	#if MSDOS_HACK
+	if (!strcmp(type->name,"msdos")) 
+		return msdos_systypes;
+	else
+	#endif
+	#if SUN_HACK
+	if (!strcmp(type->name,"sun"))
+		return sun_systypes;
+	else
+	#endif
+	#if BSD_HACK
+	if (!strcmp(type->name,"bsd"))
+		return bsd_systypes;
+	else
+	#endif
+	return NULL;
+	
+}
+
+
 /* FIXME: This is temporary, make it better, split data into a seperate file */
 const char*
 get_disk_specific_system_name (PedPartition* part) {
 	}
 	else
 	#endif
+	/* I believe these should be the same, but I'm not sure */
+	#if SUN_HACK
+	if (!strcmp(part->disk->type->name,"sun")) {
+		int i;
+		SunPartitionData *pd = (SunPartitionData *)part->disk_specific;
+		for (i = 0; sun_systypes[i].name; i++) {
+			if(sun_systypes[i].type == pd->type) {
+				return sun_systypes[i].name;
+			}
+		}
+	}
+	else
+	#endif
+	#if BSD_HACK
+	if (!strcmp(part->disk->type->name,"bsd")) {
+		int i;
+		BSDPartitionData *pd = (BSDPartitionData *)part->disk_specific;
+		for (i = 0; bsd_systypes[i].name; i++) {
+			if(bsd_systypes[i].type == pd->type) {
+				return bsd_systypes[i].name;
+			}
+		}
+	}
+	else
+	#endif
 	#if MAC_HACK
 	if (!strcmp(part->disk->type->name,"mac")) {
 		MacPartitionData *pd = (MacPartitionData *)part->disk_specific;
 	#endif
 	return NULL;
 }
+
+
+
 /* I'm lazy to write */
 #define return_system_type(ltype,stype,type_var) \
 	if (!strcmp(part->disk->type->name,(ltype))) { \
 			*size = sizeof(pd->type_var); \
 		return pd->type_var; \
 	}
+
+
+/* TODO: The size gets set to the size of the field storing the type. Maybe we
+   should make this a seperate function */
 unsigned int
 get_disk_specific_system_type (PedPartition *part, int *size) {
 	if (!part->disk_specific) {
 
 
 #ifndef SYS_TYPES_H_INCLUDED
-struct systypes {
+struct _SysType {
 	unsigned char type;
 	const char *name;
 };
+typedef struct _SysType SysType;
 #endif
 
 #define MSDOS_HACK 1
 #define MAC_HACK 1
 #define SUN_HACK 1
 #define BSD_HACK 1
-#define DVH_HACK 0
+#define DVH_HACK 1
 #define GPT_HACK 0 /* No, thank you */
 #define PC98_HACK 0
 #define AMIGA_HACK 0
 
 
 extern int is_blockdev(const char *file);
+extern SysType *get_disklabel_system_types (const PedDiskType *type);
 extern const char* get_disk_specific_system_name (PedPartition*);
 extern unsigned int get_disk_specific_system_type (PedPartition *part, int *size);
-extern struct systypes msdos_systypes[];
+
+/*
+extern SysType msdos_systypes[];
+extern SysType bsd_systypes[];
+*/
 #endif
 
 
 #ifndef HACKS_H_INCLUDED
-struct systypes {
+struct _SysType {
 	unsigned char type;
 	const char *name;
 };
+typedef struct _SysType SysType;
 #endif
 
 #define N_(String) String
 /* The system types for msdos  partition tables
  * Needed for lfdisk and some interface improvements
  */
-struct systypes msdos_systypes[] = {
+SysType msdos_systypes[] = {
 	/* TODO: I don't like some of the strings, change them */
 	{ 0x00, N_("Empty") }, /* "Empty") */
 	{ 0x01, N_("FAT12") }, 
 	{ 0, NULL }
 };
 
+SysType bsd_systypes[] = {
+	{ 0x00, N_("Unused") },
+	{ 0x01, N_("Swap") },
+	{ 0x02, N_("Version 6") },
+	{ 0x03, N_("Version 7") },
+	{ 0x04, N_("System V") },
+	{ 0x05, N_("4.1BSD") },
+	{ 0x06, N_("Eight Edition") },
+	{ 0x07, N_("4.2BSD") },
+/* It's this way in Linux fdisk, I guess it is alright */
+#ifdef __alpha__
+	{ 0x08, N_("ext2") },
+#else
+	{ 0x08, N_("MS-DOS") },
 #endif
+	{ 0x09, N_("4.4LFS") },
+	{ 0x0a, N_("Unknown") },
+	{ 0x0b, N_("HPFS") },
+	{ 0x0c, N_("ISO-9660") },
+	{ 0x0d, N_("Boot") },
+	{ 0x0e, N_("ADOS") },
+	{ 0x0f, N_("HFS") },
+	{ 0x10, N_("AdvFS") },
+	{ 0, NULL }
+};
+
+SysType sun_systypes[] = {
+	{ 0x00, N_("Empty") },
+	{ 0x01, N_("Boot") },
+	{ 0x02, N_("SunOS root") },
+	{ 0x03, N_("SunOS swap") },
+	{ 0x04, N_("SunOS usr") },
+	{ 0x05, N_("Whole disk") },
+	{ 0x06, N_("SunOS stand") },
+	{ 0x07, N_("SunOS var") },
+	{ 0x08, N_("SunOS home") },
+	{ 0x82, N_("Linux swap") },
+	{ 0x83, N_("Linux") },
+	{ 0x8e, N_("Linux LVM") },
+	{ 0xfd, N_("Lnx RAID auto") },
+	{ 0, NULL }
+};
+
+#endif
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.