1. Fabio Gonzalez
  2. fdisk

Commits

Milko Krachounov  committed b4295f3

Add support for BSD disklabel editing, which somewhat works. Fix move (add some fuzz to automatic detection of start and end in common.h). Update get_disk_specific_name to cut "Apple_" from names on a Mac partition table, only when it is required to give a shorter string (cfdisk). (fdisk@sv.gnu.org/fdisk--main--0--patch-46)
fdisk@sv.gnu.org/fdisk--main--0--patch-46
Keywords:

  • Participants
  • Parent commits 00f1987
  • Branches default

Comments (0)

Files changed (8)

File configure.ac

View file
  • Ignore whitespace
 AM_CONDITIONAL(MAKE_TESTS, test x$have_check = xtrue)
 AM_CONDITIONAL(MAKE_CFDISK, test x$have_curses = xtrue)
 
+dnl Check how to create the {g,l}fdisk links
+AC_MSG_CHECKING([How to create links])
+rm -f test00 test01
+touch test00
+ln -s test00 test01 || :
+SYMLINK=""
+SYMLINKFROM="fdisk"
+if test -L test01; then
+	SYMLINK="ln -s"
+else
+	SYMLINKFROM="${sbindir}/fdisk"
+	rm -f test01
+	ln test00 test01 || :
+	if test -e test01; then
+		SYMLINK="ln"
+	else
+		SYMLINK="cp"
+	fi
+fi
+AC_MSG_RESULT($SYMLINK)
+AC_SUBST(SYMLINK)
+AC_SUBST(SYMLINKFROM)
+rm -f test00 test01
+
 AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile tests/Makefile po/Makefile.in])
 AC_OUTPUT
 

File src/Makefile.am

View file
  • Ignore whitespace
 
 fdisk_LDADD = $(PARTED_LIBS)
 
+
+
 if MAKE_CFDISK
 sbin_PROGRAMS += cfdisk
 
 cfdisk_LDADD = $(PARTED_LIBS) $(CURSES_LIBS)
 
 endif MAKE_CFDISK
+
+install-exec-local:
+	@SYMLINK@ @SYMLINKFROM@ $(sbindir)/lfdisk
+	@SYMLINK@ @SYMLINKFROM@ $(sbindir)/gfdisk

File src/cfdisk.c

View file
  • Ignore whitespace
 			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);
+		temp = get_disk_specific_system_name(*part,0);
 		if (temp) {
 			snprintf(buf,SMALLBUF,"%30s: %s", _("System type name"), temp);
 			info = str_list_append(info,buf);
 		if (temp) {
 			snprintf(buf, SMALLBUF, "%-*s", col_label-col_fs, temp);
 		} else {
-			temp = get_disk_specific_system_name(part);
+			temp = get_disk_specific_system_name(part,1);
 			if (temp) {
 				snprintf(fsbuf, FSBUF, "[%s]", temp);
 				temp = fsbuf;

File src/common.c

View file
  • Ignore whitespace
 	 */
 	if (input && def_str && !strcmp (input, def_str)) {
 		if (!(opts & NO_RANGE)) {
-			value->range = ped_geometry_new (dev,value->sector,1);
+			if (!value->range)
+				value->range = ped_geometry_new (dev,value->sector,1);
 			ped_free (def_str);
 			ped_free (input);
 			return value->range != NULL;
 	ped_free (def_str);
 	if (!input) {
 		value->sector = 0;
-		if (!(opts & NO_RANGE))
+		if (!(opts & NO_RANGE)) {
+			if (value->range)
+				ped_geometry_destroy(value->range);
 			value->range = NULL;
+		}
 		return 0;
 	}
 
 	     part; part = ped_disk_next_partition(disk,part)) {
 		if (part->type == type) {
 			pos->start.sector = part->geom.start;
+			pos->start.range = ped_geometry_new (disk->dev,
+				 		part->geom.start, 8LL);
 			return 1;
 		}
 	}
 							pos->start.sector); 
 	if (part->type & PED_PARTITION_FREESPACE) {
 		pos->end.sector = part->geom.end;
+		pos->end.range = ped_geometry_new (disk->dev,
+				 	part->geom.end - 7LL, 8LL);
 		return 1;	
 	}
 	else

File src/fdisk.c

View file
  • Ignore whitespace
 static TimerContext timer_context;
 static FdiskCommand* fdisk_main_menu_commands[256] = {NULL};
 static FdiskCommand* fdisk_ex_menu_commands[256] = {NULL};
-static int in_ex_menu = 0;
+static FdiskCommand* fdisk_bsd_menu_commands[256] = {NULL};
+static int in_menu = 0;
 
 /* 0 = Disk was not altered.
    1 = Disk was altered. */
 		for (i=0; cmds [i]; i++)
 			fdisk_command_print_summary (cmds [i]);
 	} else {
-		if (in_ex_menu) {
+		if (in_menu == 0) {
+			for (i=0; fdisk_main_menu_commands [i]; i++)
+				fdisk_command_print_summary (fdisk_main_menu_commands [i]);
+		}
+		else if (in_menu == 1) {
 			for (i=0; fdisk_ex_menu_commands [i]; i++)
 				fdisk_command_print_summary (fdisk_ex_menu_commands [i]);
-    		} else {
-      			for (i=0; fdisk_main_menu_commands [i]; i++)
-				fdisk_command_print_summary (fdisk_main_menu_commands [i]);
+    		}
+		else if (in_menu == 2) {
+			for (i=0; fdisk_bsd_menu_commands [i]; i++)
+				fdisk_command_print_summary (fdisk_bsd_menu_commands [i]);
     		}
 	}
 }
 do_help(PedDisk** disk)
 {
 	printf (_("Command action\n"));
-	if (in_ex_menu)
+	if (in_menu == 0)
+		fdisk_print_commands_help(fdisk_main_menu_commands);
+	else if (in_menu == 1)
 		fdisk_print_commands_help(fdisk_ex_menu_commands);
-	else 
-	        fdisk_print_commands_help(fdisk_main_menu_commands);
+	else if (in_menu == 2)
+	        fdisk_print_commands_help(fdisk_bsd_menu_commands);
 	return 1;
 }
 
 static int
 do_quit (PedDisk** disk)
 {
+
 	_done ((*disk)->dev);
 
 	ped_disk_destroy (*disk);
 }
 
 static int
+is_part_type_bsd (const PedPartition* part) {
+	int type = get_disk_specific_system_type(part, NULL);
+	/* We leave these for a reference */
+	if (type == 0xa5 || type == 0xa9 || type == 0xa5 ^ 0x10 || type == 0xa9 ^ 0x10)
+		return 1;
+	return 0;
+}
+static int
 is_bsd_partition (char* device, PedSector start, PedSector s_size) {
 	int fd;
 	struct bsdlabel *lbl;
 	return 1;
 }
 
+/* FIXME: This is ugly. Won't always work. And it is untested. */
+static int
+do_edit_bsd_disklabel (PedDisk** disk)
+{
+	PedPartition *part;
+	int sect_size = (*disk)->dev->sector_size;
+
+	/* We enable external access to the device */
+	if (!ped_device_begin_external_access((*disk)->dev))
+		return 0;
+
+	/* We check if there is a BSD disklabel */
+	for (part = ped_disk_next_partition(*disk,NULL); part;
+	     part = ped_disk_next_partition(*disk,part))
+	{
+		if (part->type)
+			continue;
+		if (is_part_type_bsd(part)) {
+			/* If there is no already created BSD label created,
+			   and there is a filesystem on the partition, OR
+			   we are in gfdisk, we warn the user about it */
+			if (!is_bsd_partition((*disk)->dev->path, 
+				part->geom.start * sect_size, sect_size) && 
+				(part->type || !fdisk_compatibility_mode)) {
+				if (ped_exception_throw(PED_EXCEPTION_WARNING,
+				                        PED_EXCEPTION_YES_NO,
+				     _("There is a BSD partition on the disk, "
+				       "but there is no BSD disklabel on it. "
+				       "Do you want to create one?")) 
+					== PED_EXCEPTION_NO) {
+					ped_device_end_external_access((*disk)->dev);
+					return 0;
+				}
+			}
+			break;
+		}
+	}
+	/* FIXME: And here comes our biggest problem... */
+	if (part) {
+		PedDevice *label_dev;
+		PedDisk *label_disk;
+		char label_path[1024];
+		snprintf(label_path,sizeof(label_path),"%s%d",
+		             (*disk)->dev->path, part->num);
+		label_dev = ped_device_get(label_path);
+		if (!label_dev || ! ped_device_open(label_dev)) {
+			printf(_("There was an error opening the *BSD "
+			         "partition on %s.\n"), (*disk)->dev->path);
+			ped_device_end_external_access((*disk)->dev);
+			return 0;
+		}
+		printf("Reading disklabel of %s at sector %d.\n",
+			(*disk)->dev->path, part->geom.start);
+		label_disk = ped_disk_new(label_dev);
+		/* FIXME: This might ruin a partition on the disk */
+		if (!label_disk || strcmp(label_disk->type->name, "bsd")) {
+			label_disk = ped_disk_new_fresh (label_dev,
+					ped_disk_type_get ("bsd"));
+		}
+		in_menu = 2;
+		fdisk_interactive_menu(&label_disk, fdisk_bsd_menu_commands, 2);
+		ped_disk_destroy(label_disk);
+		ped_device_destroy(label_dev);
+		in_menu = 0;
+	} else {
+		printf(_("There is no *BSD partition on %s.\n"),
+			(*disk)->dev->path);
+		ped_device_end_external_access((*disk)->dev);
+		return 0;
+	}
+
+	ped_device_end_external_access((*disk)->dev);
+	return 1;
+
+}
 static int
 do_print (PedDisk **disk)
 {
 		int type_size;
 		unsigned int part_type = get_disk_specific_system_type (part, &type_size);
 		type_size *= 2;
-		if (type_size) {
-			printf("  %*x  %s", type_size, part_type,
-			       _(get_disk_specific_system_name(part)));
-		}
+		char *type_name = _(get_disk_specific_system_name(part,0)); 
+		if (type_size)
+			printf("  %*x  %s", type_size, part_type, type_name);
+		else if(type_name)
+			printf("  %s", type_name);
+		/* FIXME: This should not be here anymore */
 		else {
+			ped_device_begin_external_access((*disk)->dev);
 			char *type = (char *)ped_partition_type_get_name (part->type);
 			if (part->fs_type 
 				&& !strcmp (part->fs_type->name, "linux-swap"))
 				printf ("%+4s %+6s ", _("83"), _("Linux"));
 			else if (!strcmp (type, "extended"))
 				printf ("%+4s %+9s ", _("5"), _("Extended"));
+			ped_device_end_external_access((*disk)->dev);
 		}
 		#if 0
 		/* Check to see if we have a boot flag. */
 	/* FIXME: This is not needed */
 	if (!ped_disk_commit_to_os (*disk))
                 goto error;
-  
+
 	/* After writing changes exit. */
-	do_quit (disk);
+  	if (!in_menu)
+		do_quit (disk);
 
         return 1;
        
 
 static int
 do_ex_menu (PedDisk** disk) {
-	int status;
-        
-	in_ex_menu = 1;
+	int status,old_menu;
+        old_menu = in_menu;
+	in_menu = 1;
 
 	status = fdisk_interactive_menu (disk, 
 		fdisk_ex_menu_commands, 0);
 
-	in_ex_menu = 0;
+	in_menu = old_menu;
 	return status;
 }
 
 }
 
 static void
+_init_bsd_menu_commands () {
+
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("d", _("d"), NULL),
+		do_rm,
+		str_list_create (
+_(" d   delete a BSD partition"),
+NULL), NULL, 1));
+
+
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("l", _("l"), NULL),
+		do_list_systypes,
+		str_list_create (
+_(" l   list known filesystem types"),
+NULL), NULL, 1));
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("m", _("m"), NULL),
+		do_help,
+		str_list_create (
+_(" m   print this menu"),
+NULL), NULL, 1));
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("n", _("n"), NULL),
+		do_mkpart,
+		str_list_create (
+_(" n   add a new BSD partition"),
+NULL), NULL, 1));
+
+
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("p", _("p"), NULL),
+		do_print,
+		str_list_create (
+_(" p   print the BSD partition table"),
+NULL), NULL, 1));
+
+#if 0
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("q", _("q"), NULL),
+		do_quit,
+		str_list_create (
+_(" q   quit without saving changes"),
+NULL), NULL, 1));
+#endif
+
+        fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("r", _("r"), NULL),
+		NULL,
+		str_list_create (
+_(" r   return to the main menu"),
+NULL), NULL, 1));
+
+#if 0
+	/* TODO: This should be available only on msdos and sun disklabels */
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("t", _("t"), NULL),
+		do_change_system_type,
+		str_list_create (
+_(" t   change a partition's filesystem id"),
+NULL), NULL, 1));
+#endif
+
+
+	fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("u", _("u"), NULL),
+		do_unit,
+		str_list_create (
+_(" u   change display/entry units"),
+NULL), NULL, 1));
+
+        fdisk_command_register (fdisk_bsd_menu_commands, fdisk_command_create (
+		str_list_create_unique ("w", _("w"), NULL),
+		do_commit,
+		str_list_create (
+_(" w   write disklabel to disk"),
+NULL), NULL, 1));
+
+	
+}
+static void
 _init_ex_menu_commands () {
 
 
 NULL), NULL, 1));
 
 	fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
+		str_list_create_unique ("b", _("b"), NULL),
+		do_edit_bsd_disklabel,
+		str_list_create (
+_(" b   edit bsd disklabel"),
+NULL), NULL, 1));
+
+	fdisk_command_register (fdisk_main_menu_commands, fdisk_command_create (
 		str_list_create_unique ("d", _("d"), NULL),
 		do_rm,
 		str_list_create (
 		fdisk_command_destroy (*walk);
 		*walk = NULL;
 	}
+	for (walk = fdisk_bsd_menu_commands; *walk; walk++) {
+		fdisk_command_destroy(*walk);
+		*walk = NULL;
+	}
 }
 
 static void
 	dev = _choose_device (argc_ptr, argv_ptr);
 
 	_init_ex_menu_commands ();
+	_init_bsd_menu_commands ();
 	_init_main_menu_commands ();
 
 	if (!dev)

File src/hacks.c

View file
  • Ignore whitespace
 
 
 /* FIXME: This is temporary, make it better, split data into a seperate file */
+/* Returns the name of the filesystem. If short is 1, it removes the
+   "Apple_" from the name on mac partition table */
 const char*
-get_disk_specific_system_name (PedPartition* part) {
+get_disk_specific_system_name (const PedPartition* part, int brief) {
 	if (!part->disk_specific) return NULL;
 	#if MSDOS_HACK
 	if (!strcmp(part->disk->type->name,"msdos")) {
 		if (strncmp(type,"Apple_",6))
 			return NULL;
 		else {
-			int i;
-			static char buf[17];
-			for (i = 6; type[i] && i-6 < 16; i++) {
-				if (type[i] == '_')
-					buf[i-6] = ' ';
-				else
-					buf[i-6] = type[i];
-			}
-			buf[i-6] = '\0';
-			return buf;
-
+			if (brief)
+				return type+6;
+			else
+				return type;
 		}
 	}
 	else
 /* 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) {
-		*size = 0;
+get_disk_specific_system_type (const PedPartition *part, int *size) {
+	if (!part || !part->disk_specific) {
+		if (size)
+			*size = 0;
 		return 0;
 	}
 	#if MSDOS_HACK
 	return_system_type("amiga",AmigaPartitionData,de_DosType);
 	#endif
 	{
-		*size = 0;
+		if (size)
+			*size = 0;
 		return 0;
 	}
 	
 }
 /* Needed for lfdisk */
 void
-set_disk_specific_system_type (PedPartition *part, unsigned char type) {
+set_disk_specific_system_type (const PedPartition *part, unsigned char type) {
 	/* TODO: I have no idea how we actually should do this */
 	#if MSDOS_HACK
 	if (!strcmp(part->disk->type->name,"msdos")) {

File src/hacks.h

View file
  • Ignore whitespace
 
 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 const char* get_disk_specific_system_name (const PedPartition*, int brief);
+extern unsigned int get_disk_specific_system_type (const PedPartition *part, int *size);
 
 /*
 extern SysType msdos_systypes[];

File src/ui.c

View file
  • Ignore whitespace
 /* If menu equals:
  * 0 - expert menu.
  * 1 - filesystem menu. 
+ * 2 - bsd menu
  */
 int
 fdisk_interactive_menu (PedDisk** disk, FdiskCommand* cmd_list[], int menu)
 			if (!menu)
 			  fdisk_command_line_prompt_words ("Expert command (m for help)", NULL,
 							   command_names, 1);
-			else
+			else if (menu == 1)
 			  fdisk_command_line_prompt_words ("Filesystem (m for help)", NULL,
 							   command_names, 1);
+			else if (menu == 2)
+			  fdisk_command_line_prompt_words ("BSD disklabel command (m for help)", NULL,
+							   command_names, 1);
 			prompt_possibilities = 1;
 		}