Anonymous avatar Anonymous committed 087425c

Fix a missing header in tests. Add files with untested queuing code. (fdisk@sv.gnu.org/fdisk--main--0--patch-56)
fdisk@sv.gnu.org/fdisk--main--0--patch-56
Keywords:

Comments (0)

Files changed (6)

 {
 	return perform_name(*disk, NULL, NULL);
 }
+
 /* TODO: REMOVE */
 #if 0
 static void
+/*
+    GNU fdisk - a clone of Linux fdisk.
+
+    Copyright (C) 2006
+    Free Software Foundation, Inc.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#include <parted/parted.h>
+#include "queue.h"
+
+
+typedef struct {
+        PedGeometry geom;
+        const PedFileSystemType* type;
+} MkfsParameters;
+
+typedef struct {
+        PedGeometry geom;
+        PedGeometry new_geom;
+} ResizeParameters;
+
+typedef struct {
+	PedGeometry src_geom;
+        PedGeometry dst_geom;
+} CopyParameters;
+
+
+typedef struct {
+	PedPartition *part;
+} ForceParameters;
+
+Queue* queue_new (PedDisk *disk, PedTimer *timer)
+{
+	Queue *queue = malloc(sizeof(Queue));
+	queue->first = NULL;
+	queue->last = NULL;
+	queue->last_disk = disk;
+	queue->timer = timer;
+}
+
+static void* parameters_mkfs_get(va_list args)
+{
+	MkfsParameters* param;
+
+	PedGeometry		*geom = va_arg(args, PedGeometry*);
+	const PedFileSystemType	*type = va_arg(args, PedFileSystemType*);
+	
+	if (!geom || !type)
+		return NULL;
+	
+	param = malloc(sizeof(MkfsParameters));
+	
+	param->geom = *geom;
+	param->type = type;
+		
+	return param;
+}
+
+static void* parameters_resize_get(va_list args)
+{
+	ResizeParameters* param;
+
+	PedGeometry *geom	= va_arg(args, PedGeometry*);
+	PedGeometry *new_geom	= va_arg(args, PedGeometry*);
+	
+	if (!geom || !new_geom)
+		return NULL;
+	
+	param = malloc(sizeof(ResizeParameters));
+
+	param->geom = *geom;
+	param->new_geom = *new_geom;
+
+	return param;
+}
+
+static void* parameters_copy_get (va_list args)
+{
+	CopyParameters* param;
+
+	PedGeometry *src_geom = va_arg(args, PedGeometry *);
+	PedGeometry *dst_geom = va_arg(args, PedGeometry *);
+
+	if (!src_geom || !dst_geom)
+		return NULL;
+
+
+	param = malloc(sizeof(CopyParameters));
+
+	param->src_geom = *src_geom;
+	param->dst_geom = *dst_geom;
+
+	return param;
+}
+
+static void* parameters_force_get (va_list args)
+{
+	ForceParameters* param;
+	
+	PedPartition *part = va_arg(args, PedPartition*);
+	
+	param = malloc(sizeof(ForceParameters));
+	
+	/* part = NULL when it is just used for forced intermediate disk comitting */
+	param->part = part;
+	
+	return param;
+}
+
+/* Appends a new element to the queue */
+int queue_push (Queue* queue, PedDisk *prev_disk, OperationType type, ...)
+{
+	va_list args;
+	void *parameters;
+	QueueElem *new_element;
+
+	/* We get the parameters */
+	va_start (args, type);
+	switch (type) {
+		case OPER_MKFS:
+			parameters = parameters_mkfs_get(args);
+			break;
+		case OPER_RESIZE:
+			parameters = parameters_resize_get(args);
+			break;
+		case OPER_COPY:
+			parameters = parameters_copy_get(args);
+			break;
+		case OPER_FORCE_FSTYPE:
+			parameters = parameters_force_get(args);
+			break;
+	}
+	va_end(args);
+	if (!parameters)
+		return 0;
+	
+	/* We initialise the new element */
+	new_element = malloc(sizeof(QueueElem));
+
+	new_element->prev_disk = prev_disk;
+	new_element->type = type;
+	new_element->parameters = parameters;
+	new_element->next = NULL;
+
+	/* We append the element to the queue */
+	if (queue->last)
+		queue->last->next = new_element;
+	else
+		queue->first = new_element;
+	queue->last = new_element;
+
+}
+
+/* Removes the first element from the queue and returns it */
+static QueueElem* queue_shift(Queue* queue)
+{
+	QueueElem* element = queue->first;
+	if (!element)
+		return NULL;
+	queue->first = element->next;
+	if (!element->next)
+		queue->last = NULL;
+	return element;
+}
+
+/* TODO: This should be inline, but I'm not familiar with portability issues */
+static void queue_element_destroy(QueueElem *elem)
+{
+	ped_disk_destroy(elem->prev_disk);
+	free(elem->parameters);
+	free(elem);
+}
+
+/* This runs through all the changes on the disk, and fixes the fs type,
+ * if it was changed during a copy or move */
+static int fix_filesystem(QueueElem* elem, PedGeometry* geom,
+			  PedFileSystemType *fs_type)
+{
+	PedPartition *part;
+	PedDisk *disk;
+	int status = 1;
+	while (elem) {
+		disk = elem->prev_disk;
+		part = ped_disk_get_partition_by_sector(disk, geom->start);
+		if (!part)
+			break;
+		/* FIXME: If the partition has changed in size, 
+		 * we don't know what to do */
+		if (!ped_geometry_test_equal(&part->geom, geom))
+			break;
+		/* The user converted this to an extended partition */
+		if (part->type & PED_PARTITION_EXTENDED)
+			break;
+		/* The user has changed the filesystem on this one, go away */
+		if (elem->type == OPER_FORCE_FSTYPE) {
+			ForceParameters *param = elem->parameters;
+			if (param->part && ped_geometry_test_equal(&param->part->geom, geom))
+				break;
+		}
+		
+		status = status && ped_partition_set_system (part, fs_type);
+		
+		/* If this is about to get moved, or copied to, we don't care */
+		if (elem->type == OPER_RESIZE) {
+			ResizeParameters *param = elem->parameters;
+			if (ped_geometry_test_equal(&param->geom, geom))
+				break;
+		}
+		if (elem->type == OPER_COPY) {
+			CopyParameters *param = elem->parameters;
+			if (ped_geometry_test_equal(&param->dst_geom, geom))
+				break;
+		}
+		elem = elem->next;
+	}
+	return status;
+		      
+}
+
+static int commit_mkfs(QueueElem* elem, PedTimer *timer)
+{
+	MkfsParameters *param = elem->parameters;
+	
+	PedFileSystem *fs;
+	fs = ped_file_system_create(&param->geom, param->type, timer);
+	if (!fs)
+		return 0;
+	ped_file_system_close(fs);
+	return 1;
+}
+
+static int commit_resize(QueueElem* elem, PedTimer *timer)
+{
+	ResizeParameters *param = elem->parameters;
+	
+	PedFileSystem *fs;
+	int status;
+
+	fs = ped_file_system_open(&param->geom);
+	if (!fs)
+		return 0;
+	status = ped_file_system_resize(fs, &param->new_geom, timer);
+	if (status)
+		status = fix_filesystem(elem, &param->new_geom, fs->type);
+	ped_file_system_close(fs);
+	return status;
+
+}
+
+
+static int commit_copy(QueueElem* elem, PedTimer *timer)
+{
+	CopyParameters *param = elem->parameters;
+	
+	PedFileSystem *src_fs, *dst_fs;
+	int status;
+	
+	src_fs = ped_file_system_open(&param->src_geom);
+	if (!src_fs)
+		return 0;
+	dst_fs = ped_file_system_copy(src_fs, &param->dst_geom, timer);
+	ped_file_system_close(src_fs);
+	if (!dst_fs)
+		return 0;
+	status = fix_filesystem(elem, &param->dst_geom, dst_fs->type);
+	ped_filesystem_close(dst_fs);
+	return 1;
+}
+
+int queue_commit(Queue *queue)
+{
+	int status = 1;
+	/* TODO: We should commit only to disk, and should commit to system once */
+	while (queue->first) {
+		/* First we need to commit to the disk */
+		if (!ped_disk_commit(queue->first->prev_disk))
+			return 0;
+		/* Then we perform the operation */
+		switch(queue->first->type) {
+			case OPER_MKFS:
+				status = commit_mkfs(queue->first,
+				                     queue->timer);
+				break;
+			case OPER_RESIZE:
+				status = commit_resize(queue->first,
+				                       queue->timer);
+				break;
+			case OPER_COPY:
+				status = commit_copy(queue->first,
+				                     queue->timer);
+				break;
+			case OPER_FORCE_FSTYPE:
+				break;
+		}
+		if (!status)
+			return 0;
+		queue_element_destroy(queue_shift(queue));
+	
+	}
+	if(!ped_disk_commit(queue->last_disk))
+		return 0;
+}
+
+void queue_destroy(Queue *queue)
+{
+	QueueElem *element;
+	while(element = queue_shift(queue))
+		queue_element_destroy(element);
+	ped_disk_destroy(queue->last_disk);
+	ped_timer_destroy(queue->timer);
+	free(queue);
+}
+/*
+    GNU fdisk - a clone of Linux fdisk.
+
+    Copyright (C) 2006
+    Free Software Foundation, Inc.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+
+#ifndef QUEUE_H_INCLUDED
+#define QUEUE_H_INCLUDED
+
+/* NOTE: queue.{c,h} are still not in use, and lack *any* testing, it is not 
+ * known if they even compile! There are known issues with them */
+
+#include <parted/parted.h>
+
+typedef struct _Queue Queue;
+typedef struct _QueueElem QueueElem;
+
+
+typedef enum {
+	OPER_MKFS = 1,
+	OPER_RESIZE = 2,
+	OPER_COPY = 3,
+	/* We need this, because other operations in the queue may decide to modify it */
+	OPER_FORCE_FSTYPE = 4
+} OperationType;
+
+#define OPER_FORCE_SAVE OPER_FORCE_FSTYPE
+
+
+/* Each operation carries the disk just before the operation, 
+   the operation type and the needed parameters */
+struct _QueueElem {
+	PedDisk *prev_disk;
+	OperationType type;
+	void *parameters;
+	QueueElem *next;
+};
+
+struct _Queue {
+	QueueElem *first;
+	QueueElem *last;
+	PedDisk *last_disk;
+	PedTimer *timer;
+};
+
+extern Queue* queue_new (PedDisk *disk, PedTimer *timer);
+/* 
+ * A copy of the disk before performing any changes related to this operation
+ * should be given as a parameter!
+ */
+extern int queue_push(Queue*, PedDisk* prev, OperationType, ...);
+/*
+ * queue_push(Queue*, PedDisk*, OPER_MKFS, PedGeometry*, PedFileSystemType*)
+ * queue_push(Queue*, PedDisk*, OPER_RESIZE, PedGeometry* old, PedGeometry* new)
+ * queue_push(Queue*, PedDisk*, OPER_COPY, PedGeometry* src, PedGeometry* dst)
+ * queue_push(Queue*, PedDisk*, OPER_FORCE_FSTYPE, PedPartition*)
+ * queue_push(Queue*, PedDisk*, OPER_FORCE_SAVE, NULL)
+ */
+
+extern int queue_commit(Queue*);
+extern void queue_destroy(Queue*);
+
+
+#endif

tests/check_common.c

 #include <stdlib.h>
 #include <check.h>
 #include <stdio.h>
+#include <string.h>
 #include <parted/parted.h>
 #include "../src/strlist.h"
 #include "../src/common.h"

tests/functions.c

 #include <sys/stat.h>
 #include <parted/parted.h>
 /* #include <endian.h> */
+#include <string.h>
 #include "../src/strlist.h"
 #include "functions.h"
 #include "../src/common.h"
 
 int partpos;
 int pos_gets;
-char pos_poss[10];
+char pos_poss[POS_POSS_SIZE];
 int getpartpos (const char* prompt, const void* context,
                        const char *possibilities)
 {

tests/functions.h

 extern PedFileSystemType *fs_type;
 extern int getfstype (const char* prompt, PedFileSystemType **value);
 
+
+#define POS_POSS_SIZE 10
 extern int partpos;
 extern int pos_gets;
-extern char pos_poss[10];
+extern char pos_poss[POS_POSS_SIZE];
 extern int getpartpos (const char* prompt, const void* context,
                        const char *possibilities);
 
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.