Anonymous avatar Anonymous 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:

Comments (0)

Files changed (8)

 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
 
 
 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
 			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;
 	 */
 	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
 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)
 
 
 /* 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")) {
 
 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[];
 /* 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;
 		}
 
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.