[PC-BSD Commits] r7415 - pcbsd-projects/txt-sysinstall

svn at pcbsd.org svn at pcbsd.org
Fri Aug 20 17:08:09 PDT 2010


Author: johnh
Date: 2010-08-20 17:08:09 -0700 (Fri, 20 Aug 2010)
New Revision: 7415

Modified:
   pcbsd-projects/txt-sysinstall/TODO
   pcbsd-projects/txt-sysinstall/components.c
   pcbsd-projects/txt-sysinstall/disksel.c
   pcbsd-projects/txt-sysinstall/label.c
   pcbsd-projects/txt-sysinstall/mainmenu.c
   pcbsd-projects/txt-sysinstall/medium.c
   pcbsd-projects/txt-sysinstall/packages.c
   pcbsd-projects/txt-sysinstall/partsel.c
   pcbsd-projects/txt-sysinstall/rootpass.c
   pcbsd-projects/txt-sysinstall/txt-sysinstall.h
   pcbsd-projects/txt-sysinstall/tzone.c
   pcbsd-projects/txt-sysinstall/useradd.c
   pcbsd-projects/txt-sysinstall/util.c
Log:
Added support for disk labeling, some initial work on next / back
handling, DMENU macros, gmirror option, zfs options, encryption, etc.
It's a bit messy and needs cleanup and testing, more to come.


Modified: pcbsd-projects/txt-sysinstall/TODO
===================================================================
--- pcbsd-projects/txt-sysinstall/TODO	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/TODO	2010-08-21 00:08:09 UTC (rev 7415)
@@ -1,9 +1,7 @@
 * test install dvd
 * test install pc-bsd
-* add support for labeling the disk
 * support upgrade mode
 * add a inputbox to let the user type an URL when installing via FTP
-* replace all the remaining menu setup with the DMENU() macro
 * use or develop a library to support i18n
 * test the code with ndialog and think about using ndialog instead (we can import ndialog into freebsd)
 * play with style.rc ;-)

Modified: pcbsd-projects/txt-sysinstall/components.c
===================================================================
--- pcbsd-projects/txt-sysinstall/components.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/components.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -149,7 +149,7 @@
 			}
 		}
 
-		if (ptr[0] != 0)
+		if (notnull(ptr))
 			appendconfig("installComponents", compstr);
 	}
 

Modified: pcbsd-projects/txt-sysinstall/disksel.c
===================================================================
--- pcbsd-projects/txt-sysinstall/disksel.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/disksel.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -34,74 +34,40 @@
 #include "txt-sysinstall.h"
 
 #define MODULE "Disk Selection"
-#define MAXDISKS 12
 
 
-static void
-free_partsel(void *args)
-{
-	struct partsel *p = (struct partsel *)args;
-	if (p != NULL) {
-		free(p->disk);
-		free(p->diskname);
-		free(p);
-	}
-}
-
 static int
 disk_fire(dialogMenuItem *self)
 {
-	struct partsel *p;
+	struct disk_info *di;
 	appendconfig("disk0", self->prompt);
 
-	p = safe_malloc(sizeof(*p));
-	if (self->prompt)
-		p->disk = safe_strdup(self->prompt);
-	if (self->title)
-		p->diskname = safe_strdup(self->title);
+	di = (struct disk_info *)self->data;
+	di->used = 1;
 
-	set_next_dialog(&dialog_partsel, p, &free_partsel);
+	set_next_dialog("partsel", &dialog_partsel, di, NULL);
 	return (0);
 }
 
 int
 dialog_disksel(void *args)
 {
-	char *buf;
-	char *token;
 	dialogMenuItem *menus;
-	int status;
+	struct disk_list *disks;
+	struct disk_info *di;
 	int i;
 
-	buf = safe_malloc(BUFSZ+1);
-	status = run_pcsysinstall(buf, BUFSZ, "disk-list", NULL);
-	menus = safe_malloc(sizeof(*menus)*MAXDISKS+3);
-
 	i = 0;
+	disks = get_disk_list();
+	menus = safe_malloc(sizeof(*menus) * (disks->ndisks + 2));
 	DMENUF(&menus[i++], "Next", NULL, NULL);
 	DMENUF(&menus[i++], "Back", NULL, NULL);
 
-	while ((token = strsep(&buf, "\n")) != NULL && safe_strlen(token) > 0 &&
-	    i < MAXDISKS+2) {
-		char *disk;
-
-		menus[i].prompt = strsep(&token, ":");
-		disk = strsep(&token, ":");
-		/* trim string and remove '<' and '>' */
-		disk += 2;
-		disk[safe_strlen(disk)-1] = 0;
-		menus[i].title = disk;
-		menus[i].fire  = disk_fire;
-		i++;
+	STAILQ_FOREACH(di, &disks->list, entries) {
+		DMENUFD(&menus[i++], di->disk,
+			di->desc == NULL ? "" : di->desc, disk_fire, di);
 	}
 
-#ifdef DEBUG
-	menus[i].prompt = "md0";
-	menus[i].title  = "";
-	menus[i].fire   = disk_fire;
-	i++;
-#endif
-
 	screen_clear(MODULE);
 	dialog_menu(MODULE,
 	    "Please select the disk on which you want to install "
@@ -109,7 +75,5 @@
 	    7+i-2, 70, i-2, -i+2, menus+2, "", NULL, NULL);
 
 	free(menus);
-	free(buf);
-
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/label.c
===================================================================
--- pcbsd-projects/txt-sysinstall/label.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/label.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -30,12 +30,677 @@
 #include <string.h>
 #include <stdlib.h>
 #include <dialog.h>
+#include <libutil.h>
+#include <limits.h>
 
 #include "txt-sysinstall.h"
 
 #define MODULE "Disk label setup"
 #define MAXLABELS 64
+#define	MAXTYPES 10	
+#define	MAXZPOOLS 14
 
+#define	FS_UFS					0x01	
+#define	FS_ZFS					0x02
+#define	FS_SWAP					0x03
+
+#define	FS_FLAGS_GJOURNAL		0x000001
+#define	FS_FLAGS_SOFTUPDATES	0x000002
+#define	FS_FLAGS_ENCRYPT		0x000004
+
+#define	ZFS_POOL_BASIC			0x000010
+#define	ZFS_POOL_MIRROR			0x000020
+#define	ZFS_POOL_RAIDZ			0x000040
+#define	ZFS_POOL_RAIDZ1			ZFS_POOL_RAIDZ	
+#define	ZFS_POOL_RAIDZ2			0x000080
+#define	ZFS_POOL_DISK			0x000100
+#define	ZFS_POOL_FILE			0x000200
+#define	ZFS_POOL_SPARE			0x000400
+#define	ZFS_POOL_LOG			0x000800
+#define	ZFS_POOL_CACHE			0x001000
+
+#define	FS_ZERO(x)				(x = 0)
+#define	GET_FS_TYPE(type) 		(type & 0x000000ff)
+#define	GET_FS_FLAGS(type)		((type & 0xffffff00) >> 24)
+#define	SET_FS_TYPE(x, type)	(x = (x | type))	
+#define CLEAR_FS_TYPE(x, type)	(x = (x & ~type))
+#define	SET_FS_FLAGS(x, flags)	(x = (x | (flags << 24)))
+#define CLEAR_FS_F(x, flags)	(x = (x & ~(flags << 24)))
+#define	FS_FLAG_SET(x, flags)	(x & (flags << 24))
+#define	FS_TYPE_SET(x, type)	(x & type)
+
+struct label_info {
+	char *label;
+	char *desc;
+	char *password;
+	size_t size;
+	long flags;
+	int selected;
+	STAILQ_ENTRY(label_info) entries;
+};
+STAILQ_HEAD(label_info_head, label_info) label_info_list =
+	STAILQ_HEAD_INITIALIZER(label_info_list);
+
+struct zpool_disk {
+	struct disk_info *di;
+	int selected;
+	STAILQ_ENTRY(zpool_disk) entries;
+};
+STAILQ_HEAD(zpool_disk_head, zpool_disk) zpool_disk_list = 
+	STAILQ_HEAD_INITIALIZER(zpool_disk_list);
+
+struct zfs_mount {
+	char *path;
+	STAILQ_ENTRY(zfs_mount) entries;
+};
+STAILQ_HEAD(zfs_mount_head, zfs_mount) zfs_mount_list = 
+	STAILQ_HEAD_INITIALIZER(zfs_mount_list);
+
+
+static void
+add_label(const char *label, const char *desc, char *password, size_t size, long flags)
+{
+	struct label_info *li;
+
+	li = safe_malloc(sizeof(*li));
+	li->label = safe_strdup(label);
+	li->desc = safe_strdup(desc);
+	li->password = safe_strdup(password);
+	li->size = size;
+	li->flags = flags;
+	li->selected = 0;
+
+	STAILQ_INSERT_TAIL(&label_info_list, li, entries);
+}
+
+static int
+label_exists(const char *label)
+{
+	int exists = 0;
+	struct label_info *li;
+
+	STAILQ_FOREACH(li, &label_info_list, entries) {
+		if (strcmp(label, li->label) == 0) {
+			exists = 1;
+			break;
+		}
+	}
+
+	return (exists);
+}
+
+static const char *
+zpool_type_to_string(unsigned long type)
+{
+	const char *str = NULL;
+
+	switch (type) {
+		case ZFS_POOL_BASIC:
+			str = "";
+			break;
+
+		case ZFS_POOL_MIRROR:
+			str = "mirror";
+			break;
+
+		case ZFS_POOL_RAIDZ1:
+			str = "raidz1";
+			break;
+
+		case ZFS_POOL_RAIDZ2:
+			str = "raidz2";
+			break;
+
+		case ZFS_POOL_DISK:
+			str = "disk";
+			break;
+
+		case ZFS_POOL_FILE:
+			str = "file";
+			break;
+
+		case ZFS_POOL_SPARE:
+			str = "spare";
+			break;
+
+		case ZFS_POOL_LOG:
+			str = "log";
+			break;
+
+		case ZFS_POOL_CACHE:
+			str = "cache";
+			break;
+	}
+
+	return (str);
+}
+
+static char *
+zpool_disk_list_to_string(unsigned long type)
+{
+	char *diskstr;
+	char buf[2048];
+	struct zpool_disk *zd;
+
+	bzero(&buf, sizeof(buf));
+	STAILQ_FOREACH(zd, &zpool_disk_list, entries) {
+		struct disk_info *di = zd->di;
+		strlcat(buf, di->disk, sizeof(buf));
+		strlcat(buf, " ", sizeof(buf));
+	}
+
+	diskstr = NULL;
+	if (!empty(buf)) {
+		const char *typestr = zpool_type_to_string(type);
+		char str[2048];
+
+		buf[safe_strlen(buf) - 1] = 0;
+
+		bzero(&str, sizeof(str));
+		if (notnull(typestr))
+			snprintf(str, sizeof(str), "(%s: %s)", typestr, buf);
+		else
+			snprintf(str, sizeof(str), "(%s)", buf);
+
+		diskstr = safe_strdup(str);
+	}
+
+	return (diskstr);
+}
+
+
+static void
+get_password(char *module, char *password)
+{
+	int loop;
+	unsigned char password1[128];
+	unsigned char password2[128];
+
+	DialogInputAttrs |= DITEM_NO_ECHO;
+
+	loop = 1;
+	while (loop) {
+		bzero(&password1, sizeof(password1));
+		bzero(&password2, sizeof(password2));
+
+		screen_clear("PASSWORD");
+		dialog_inputbox(module, "Password", 8, 60, password1);
+		dialog_inputbox(module, "Confirm", 8, 60, password2);
+
+		if (strncmp(password1, password2, sizeof(password2)) == 0) {
+			strlcpy(password, password1, sizeof(password1));	
+			loop = 0;
+		}
+	}
+
+	DialogInputAttrs &= ~DITEM_NO_ECHO;
+}
+
+static int
+ufs_fire(dialogMenuItem *self)
+{
+	int loop;
+	int enc;
+	long flags;
+	int64_t size;
+	int64_t mb;
+	char buf[64];
+	char mnt[1024];
+	char password[64];
+
+	bzero(&buf, sizeof(buf));
+	bzero(&mnt, sizeof(mnt));
+	screen_clear("UFS");
+
+	FS_ZERO(flags);
+	SET_FS_TYPE(flags, FS_UFS);
+
+	dialog_inputbox("UFS", "Size", 8, 70, buf);
+	expand_number(buf, &size);
+	b2mb(&size, &mb);
+
+	loop = 1;
+	while (loop == 1) {
+		bzero(&mnt, sizeof(mnt));
+		dialog_inputbox("UFS", "Mount Point", 8, 70, mnt);
+		if (label_exists(mnt)) {
+			snprintf(buf, sizeof(buf), "%s already specified", mnt);
+			dialog_notify(buf);
+			continue;
+		}
+
+		loop = 0;
+	}
+
+	enc = dialog_noyes("UFS", "Encrypt?", 8, 10);
+	if (enc == 0) {
+		SET_FS_FLAGS(flags, FS_FLAGS_ENCRYPT);
+		bzero(&password, sizeof(password));
+		get_password("UFS", password);
+	}
+
+	if (self->aux != 0)
+		SET_FS_FLAGS(flags, self->aux);
+
+	add_label(mnt, NULL, password, mb, flags);
+	return (0);
+}
+
+static int
+zpool_fire(dialogMenuItem *self)
+{
+	*((unsigned long *)self->data) = self->aux;
+	return (0);
+}
+
+static int
+zpool_disk_fire(dialogMenuItem *self)
+{
+	if (self->data) {
+		struct zpool_disk *zd = self->data;
+		zd->selected = !zd->selected;
+		return (DITEM_SUCCESS);
+	}
+
+	return (DITEM_FAILURE);
+}
+
+static int
+zpool_disk_checked(dialogMenuItem *self)
+{
+	struct zpool_disk *zd = self->data;
+	if (zd->selected)
+		return (TRUE);
+
+	return (FALSE);
+}
+
+static void
+get_zfs_zpool_type(unsigned long *type)
+{
+	int i;
+	dialogMenuItem *menus;
+
+	i = 0;
+	menus = safe_malloc(sizeof(*menus)*(MAXZPOOLS+2));
+	DMENUF(&menus[i++], "Next", NULL, NULL);
+	DMENUF(&menus[i++], "Back", NULL, NULL);
+	DMENUFDA(&menus[i++], "basic", "", &zpool_fire,
+		type, ZFS_POOL_BASIC);
+	DMENUFDA(&menus[i++], "disk", "", &zpool_fire,
+		type, ZFS_POOL_DISK);
+	DMENUFDA(&menus[i++], "file", "", &zpool_fire,
+		type, ZFS_POOL_FILE);
+	DMENUFDA(&menus[i++], "mirror", "", &zpool_fire,
+		type, ZFS_POOL_MIRROR);
+	DMENUFDA(&menus[i++], "raidz", "", &zpool_fire,
+		type, ZFS_POOL_RAIDZ);
+	DMENUFDA(&menus[i++], "raidz1", "", &zpool_fire,
+		type, ZFS_POOL_RAIDZ1);
+	DMENUFDA(&menus[i++], "raidz2", "", &zpool_fire,
+		type, ZFS_POOL_RAIDZ2);
+	DMENUFDA(&menus[i++], "spare", "", &zpool_fire,
+		type, ZFS_POOL_SPARE);
+	DMENUFDA(&menus[i++], "log", "", &zpool_fire,
+		type, ZFS_POOL_LOG);
+	DMENUFDA(&menus[i++], "cache", "", &zpool_fire,
+		type, ZFS_POOL_CACHE);
+
+	screen_clear("ZFS");
+	dialog_menu("ZFS", "ZFS Pool Type",
+		7+i-2, 40, i-2, -i+2,
+		menus+2, "", NULL, NULL);
+	
+	free(menus);
+}
+
+static void
+get_zfs_zpool_disks(void)
+{
+	int i;
+	dialogMenuItem *menus;
+	struct disk_info *di;
+	struct disk_list *disks;
+	struct zpool_disk *zpool_disks;
+
+	i = 0;
+	disks = get_disk_list();
+	zpool_disks = safe_malloc(sizeof(*zpool_disks) * (disks->ndisks + 2));
+
+	menus = safe_malloc(sizeof(*menus) * (disks->ndisks + 2));
+	DMENUF(&menus[i++], "Next", NULL, NULL);
+	DMENUF(&menus[i++], "Back", NULL, NULL);
+	STAILQ_FOREACH(di, &disks->list, entries) {
+		if (di->used)
+			continue;
+
+		zpool_disks[i].di = di;
+		zpool_disks[i].selected = 0;
+		DMENUFCD(&menus[i], di->disk,  "", &zpool_disk_fire,
+			&zpool_disk_checked, &zpool_disks[i]);
+		i++;
+	}
+
+	screen_clear("ZFS");
+	dialog_checklist("ZFS", "ZFS Pool Devices",
+		7+i-2, 60, i-2, -i+2, menus+2, "");
+
+	for (i = 0;i < (int)(disks->ndisks + 2);i++) {
+		if (zpool_disks[i].selected) {
+			struct zpool_disk *disk;
+
+			disk = safe_malloc(sizeof(*disk));
+			disk->di = zpool_disks[i].di;
+			disk->selected = zpool_disks[i].selected;
+			STAILQ_INSERT_TAIL(&zpool_disk_list, disk, entries);
+		}
+
+		zpool_disks[i].di = NULL;
+	}
+
+	free(zpool_disks);
+}
+
+static void
+get_zfs_mount_points(char **pptr)
+{
+	int res;
+	size_t bytes;
+	char mnt[PATH_MAX];
+	struct zfs_mount *temp, *z;
+
+	res = 0;
+	bytes = 0;
+	while (res == 0) {
+		bzero(&mnt, sizeof(mnt));
+		screen_clear("ZFS");
+
+		res = dialog_inputbox("ZFS", "Mount Point", 8, 70, mnt);
+		if (empty(mnt))
+			continue;
+
+		if (label_exists(mnt)) {
+			char buf[1024];
+			snprintf(buf, sizeof(buf), "%s already specified", mnt);
+			dialog_notify(buf);
+			continue;
+		}
+
+		if (res == 0) {
+			struct zfs_mount *zm;
+
+			zm = safe_malloc(sizeof(*zm));
+			zm->path = safe_strdup(mnt);
+			STAILQ_INSERT_TAIL(&zfs_mount_list, zm, entries);
+
+			bytes += safe_strlen(mnt) + 2;
+		}
+	}
+
+	*pptr = safe_malloc(bytes + 1);
+	STAILQ_FOREACH_SAFE(z, &zfs_mount_list, entries, temp) {
+		strlcat(*pptr, z->path, bytes);
+		strlcat(*pptr, ",", bytes);
+
+		STAILQ_REMOVE(&zfs_mount_list, z, zfs_mount, entries);
+		free(z->path);
+		free(z);
+	}
+
+	(*pptr)[strlen(*pptr) - 1] = 0;
+}
+
+static int
+zfs_fire(dialogMenuItem *self)
+{
+	int enc;
+	long flags;
+	int64_t size;
+	int64_t mb;
+	unsigned long type;
+	char buf[1024];
+	char password[64];
+	char *mount_points;
+
+	bzero(&buf, sizeof(buf));
+	screen_clear("ZFS");
+
+	FS_ZERO(flags);
+	SET_FS_TYPE(flags, FS_ZFS);
+
+	dialog_inputbox("ZFS", "Size", 8, 70, buf);
+	expand_number(buf, &size);
+	b2mb(&size, &mb);
+
+	type = 0;
+	mount_points = NULL;
+
+	get_zfs_zpool_type(&type);
+	SET_FS_FLAGS(flags, type);
+
+	get_zfs_zpool_disks();
+	get_zfs_mount_points(&mount_points);
+
+	enc = dialog_noyes("ZFS", "Encrypt?", 8, 10);
+	if (enc == 0) {
+		SET_FS_FLAGS(flags, FS_FLAGS_ENCRYPT);
+		bzero(&password, sizeof(password));
+		get_password("ZFS", password);
+	}
+
+	if (self->aux != 0)
+		SET_FS_FLAGS(flags, self->aux);
+
+	add_label(mount_points, NULL, password, mb, flags);
+	free(mount_points);
+
+	return (0);
+}
+
+static int
+swap_fire(dialogMenuItem *self)
+{
+	int enc;
+	long flags;
+	int64_t size;
+	int64_t mb;
+	char buf[64];
+	char password[64];
+
+	screen_clear("SWAP");
+
+	FS_ZERO(flags);
+	SET_FS_TYPE(flags, FS_SWAP);
+
+	bzero(&buf, sizeof(buf));
+	dialog_inputbox("SWAP", "Size", 8, 70, buf);
+
+	expand_number(buf, &size);
+	b2mb(&size, &mb);
+
+	enc = dialog_noyes("SWAP", "Encrypt?", 8, 10);
+	if (enc == 0) {
+		SET_FS_FLAGS(flags, FS_FLAGS_ENCRYPT);
+		bzero(&password, sizeof(password));
+		get_password("SWAP", password);
+	}
+
+	if (self->aux != 0)
+		SET_FS_FLAGS(flags, self->aux);
+
+	add_label("SWAP", NULL, password, mb, flags);
+	return (0);
+}
+
+
+static int
+dialog_partition(void)
+{
+	int i;
+	int res;
+	unsigned long data;
+	dialogMenuItem *menus;
+
+	i = 0;
+	menus = safe_malloc(sizeof(*menus)*MAXTYPES+2);
+	DMENUF(&menus[i++], "Next", NULL, NULL);
+	DMENUF(&menus[i++], "Back", NULL, NULL);
+
+	data = 0;
+	DMENUFD(&menus[i++], "UFS", "UFS filesystem",
+		ufs_fire, &data);
+
+	DMENUFDA(&menus[i++], "UFS+S", "UFS + soft updates",
+		ufs_fire, &data, FS_FLAGS_SOFTUPDATES);
+
+	DMENUFDA(&menus[i++], "UFS+J", "UFS + gjournal",
+		ufs_fire, &data, FS_FLAGS_GJOURNAL);
+
+	DMENUFD(&menus[i++], "ZFS", "zeta filesystem",
+		zfs_fire, &data);
+
+	DMENUFD(&menus[i++], "SWAP", "swap partition" ,
+		swap_fire, &data);
+
+	res = 0;
+	while (res == 0) {
+		screen_clear(MODULE);
+		res = dialog_menu(MODULE, "Please select a filesystem:",
+			-1, 60, 7, -i+2, menus+2, "", NULL, NULL);
+	}
+	
+	free(menus);
+	return (res);
+}
+
+
+static void
+write_disk_labels(void)
+{
+	struct label_info *li;
+
+	STAILQ_FOREACH(li, &label_info_list, entries) {
+		char line[8192];
+		char num[32];
+
+		bzero(&num, sizeof(num));
+		snprintf(num, sizeof(num), "%ld", li->size);
+
+		bzero(&line, sizeof(line));
+		switch (GET_FS_TYPE(li->flags)) {
+			case FS_UFS: {
+				strlcpy(line, "UFS", sizeof(line));
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_GJOURNAL))
+					strlcat(line, "+J", sizeof(line));
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_SOFTUPDATES))
+					strlcat(line, "+S", sizeof(line));
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					strlcat(line, ".eli", sizeof(line));
+
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, num, sizeof(line));
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, li->label, sizeof(line));
+
+				appendconfig("disk0-part", line);
+
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					appendconfig("encpass", li->password);
+
+				break;
+			}
+
+			case FS_ZFS: {
+				char *diskstr;
+				unsigned long zpool;
+
+				strlcpy(line, "ZFS", sizeof(line));
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					strlcat(line, ".eli", sizeof(line));
+				
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, num, sizeof(line));
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, li->label, sizeof(line));
+
+				zpool = 0;
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_BASIC))
+					zpool = ZFS_POOL_BASIC;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_MIRROR))
+					zpool = ZFS_POOL_MIRROR;
+		
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_RAIDZ1))
+					zpool = ZFS_POOL_RAIDZ1;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_RAIDZ2))
+					zpool = ZFS_POOL_RAIDZ2;
+	
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_DISK))
+					zpool = ZFS_POOL_DISK;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_FILE))
+					zpool = ZFS_POOL_FILE;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_SPARE))
+					zpool = ZFS_POOL_SPARE;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_LOG))
+					zpool = ZFS_POOL_LOG;
+
+				if (FS_FLAG_SET(li->flags, ZFS_POOL_CACHE))
+					zpool = ZFS_POOL_CACHE;
+
+				diskstr = zpool_disk_list_to_string(zpool);
+				if (notnull(diskstr)) {
+					strlcat(line, " ", sizeof(line));
+					strlcat(line, diskstr, sizeof(line));
+					free(diskstr);
+				}
+
+				appendconfig("disk0-part", line);
+
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					appendconfig("encpass", li->password);
+
+				break;
+			}
+
+			case FS_SWAP: {
+				strlcpy(line, "SWAP", sizeof(line));
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					strlcat(line, ".eli", sizeof(line));
+
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, num, sizeof(line));
+				strlcat(line, " ", sizeof(line));
+				strlcat(line, li->label, sizeof(line));
+
+				appendconfig("disk0-part", line);
+
+				if (FS_FLAG_SET(li->flags, FS_FLAGS_ENCRYPT))
+					appendconfig("encpass", li->password);
+				break;
+			}
+		}
+	}
+}
+
+static int
+label_fire(dialogMenuItem *self)
+{
+	const char *disk;
+	struct disk_info *di;
+
+	disk = getconfigval("disk0");
+	di = get_disk_info(disk, NULL);
+
+	dialog_partition();
+
+	free_disk_info((void *)di);
+	return (0);
+}
+
 int
 dialog_label(void *args)
 {
@@ -47,10 +712,11 @@
 
 	buf = safe_malloc(BUFSZ+1);
 	status = run_pcsysinstall(buf, BUFSZ, "sys-mem", NULL);
-	swap = atoi(buf) * 2;
+	swap = atoi(buf) * 2 + 2048;
 	free(buf);
 
-	if (dialog_noyes(MODULE,
+	screen_clear(MODULE);
+	if (dialog_yesno(MODULE,
 	    "Do you wish to configure your BSD label?\n\n"
 	    "<give a brief explanation of what are BSD labels>", 8, 60)) {
 		char value[64];
@@ -58,33 +724,29 @@
 		/*
 		 * This is the default label configuration.
 		 */
-		appendconfig("disk0-part", "UFS+S 1000 /");
+		appendconfig("disk0-part", "UFS+S 1024 /");
 		snprintf(value, sizeof(value), "SWAP %d none", swap);
 		appendconfig("disk0-part", value);
 		appendconfig("disk0-part", "UFS+S 0 /usr");
 		appendconfig("commitDiskLabel", NULL);
 
-		dialog_useradd(NULL);
+		set_next_dialog("useradd", &dialog_useradd, NULL, NULL);
 		return (0);
 	}
 
+	i = 0;
 	menus = safe_malloc(sizeof(*menus)*MAXLABELS+2);
-
-	i = 0;
 	DMENUF(&menus[i++], "Next", NULL, NULL);
 	DMENUF(&menus[i++], "Back", NULL, NULL);
-	DMENUF(&menus[i++], "-", "", NULL);
-	DMENUF(&menus[i++], "/   \t1GB", "UFS+S", NULL);
-	DMENUF(&menus[i++], "SWAP\t2GB", "SWAP", NULL);
-	DMENUF(&menus[i++], "/usr\t4GB", "UFS+S", NULL);
-	DMENUF(&menus[i++], "-", "", NULL);
-	DMENUF(&menus[i++], "Add a new BSD partition", "", NULL);
+	DMENUF(&menus[i++], "Add Label", "", label_fire);
 
 	screen_clear(MODULE);
-	dialog_menu(MODULE, "BSD partitions:", 19, 70, 12, -i+2,
-	    menus+2, "", NULL, NULL);
+	dialog_menu(MODULE, "BSD partitions:", 12, 50, 3, -i+2,
+    	menus+2, "", NULL, NULL);
+
 	free(menus);
+	write_disk_labels();
 
-	set_next_dialog(&dialog_useradd, NULL, NULL);
+	set_next_dialog("useradd", &dialog_useradd, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/mainmenu.c
===================================================================
--- pcbsd-projects/txt-sysinstall/mainmenu.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/mainmenu.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -42,7 +42,7 @@
 static int
 next_fire(dialogMenuItem *self)
 {
-	set_next_dialog(&dialog_disksel, NULL, NULL);
+	set_next_dialog("disksel", &dialog_disksel, NULL, NULL);
 	return (0);
 }
 
@@ -57,7 +57,7 @@
 install_fire(dialogMenuItem *self)
 {
 	appendconfig("installMode", "fresh");
-	set_next_dialog(&dialog_disksel, NULL, NULL);
+	set_next_dialog("disksel", &dialog_disksel, NULL, NULL);
 
 	return (0);
 }
@@ -66,7 +66,7 @@
 upgrade_fire(dialogMenuItem *self)
 {
 	appendconfig("installMode", "upgrade");
-	set_next_dialog(&dialog_disksel, NULL, NULL);
+	set_next_dialog("disksel", &dialog_disksel, NULL, NULL);
 
 	return (0);
 }
@@ -74,7 +74,7 @@
 static int
 netif_fire(dialogMenuItem *self)
 {
-	set_next_dialog(&dialog_netif, NULL, NULL);
+	set_next_dialog("netif", &dialog_netif, NULL, NULL);
 	return (0);
 }
 

Modified: pcbsd-projects/txt-sysinstall/medium.c
===================================================================
--- pcbsd-projects/txt-sysinstall/medium.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/medium.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -82,6 +82,6 @@
 	dialog_menu(MODULE, "Please select the install medium:",
 	    7+i-2, 70, i-2, -i+2, menus+2, "", NULL, NULL);
 
-	set_next_dialog(&PKGFUNC, NULL, NULL);
+	set_next_dialog("packages", &PKGFUNC, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/packages.c
===================================================================
--- pcbsd-projects/txt-sysinstall/packages.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/packages.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -333,7 +333,7 @@
 		}
 	}
 
-	if (ptr[0] != 0)
+	if (notnull(ptr))
 		appendconfig("installPackages", pkgstr);
 
 	free(pkgstr);

Modified: pcbsd-projects/txt-sysinstall/partsel.c
===================================================================
--- pcbsd-projects/txt-sysinstall/partsel.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/partsel.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -36,153 +36,158 @@
 
 #define MODULE		"Partition Manager"
 #define MAXPARTS	64
-#define	MAXTYPES	10	
 
-#define	FS_UFS					0x00000001
-#define	FS_ZFS					0x00000002
-#define	FS_SWAP					0x00000003
-#define	FS_MIRROR				0x00000004
-
-#define	FS_FLAGS_GJOURNAL		0x00010000
-#define	FS_FLAGS_SOFTUPDATES	0x00020000	
-#define	FS_FLAGS_ENCRYPT		0x00040000
-#define	FS_FLAGS_MIRROR			0x00080000
-
-#define	ZFS_POOL_BASIC			0x00010000
-#define	ZFS_POOL_MIRROR			0x00020000
-#define	ZFS_POOL_RAIDZ			0x00040000	
-
-#define	MIRROR_LOAD				0x00100000
-#define	MIRROR_PREFER			0x00200000
-#define	MIRROR_ROUNDROBIN		0x00400000
-#define	MIRROR_SPLIT			0x00800000
-
-#define	GET_FS_TYPE(type) 		(type & 0xffff0000)
-#define	GET_FS_FLAGS(type)		(type & 0x0000ffff)
-
 enum {
 	USEALL  = 1,
 	USENEW  = 2
 };
 
+struct mirror_disk {
+	char disk[128];
+	char balance[128];
+};
+
 static int
-ufs_fire(dialogMenuItem *self)
+part_fire(dialogMenuItem *self)
 {
-	long flags;
+	switch (self->aux) {
+	case USEALL:
+		appendconfig("partition", "all");
+		break;
 
-	flags = GET_FS_FLAGS(self->aux);
+	case USENEW:
+		appendconfig("partition", "free");
+		break;
 
+	default:
+		appendconfig("partition", self->prompt);
+	}
+
 	return (0);
 }
 
 static int
-zfs_fire(dialogMenuItem *self)
+gmirror_disk_fire(dialogMenuItem *self)
 {
-	long flags;
+	struct mirror_disk *md = self->data;
 
-	flags = GET_FS_FLAGS(self->aux);
-
-	return (0);
+	strcpy(md->disk, self->prompt);
+	return (DITEM_SUCCESS);
 }
 
 static int
-swap_fire(dialogMenuItem *self)
+gmirror_disk_checked(dialogMenuItem *self)
 {
-	long flags;
+	struct mirror_disk *md = self->data;
 
-	flags = GET_FS_FLAGS(self->aux);
+	if (strcmp(md->disk, self->prompt) == 0)
+		return (TRUE);
 
-	return (0);
+	return (FALSE);
 }
 
 static int
-mirror_fire(dialogMenuItem *self)
+gmirror_balance_fire(dialogMenuItem *self)
 {
-	long flags;
+	struct mirror_disk *md = self->data;
 
-	flags = GET_FS_FLAGS(self->aux);
+	strcpy(md->balance, self->prompt);
+	return (DITEM_SUCCESS);
+}
 
-	return (0);
+static int
+gmirror_balance_checked(dialogMenuItem *self)
+{
+	struct mirror_disk *md = self->data;
+
+	if (strcmp(md->balance, self->prompt) == 0)
+		return (TRUE);
+
+	return (FALSE);
 }
 
-static void
-dialog_partition(char *prompt)
+static struct mirror_disk *
+configure_gmirror(void)
 {
 	int i;
-	char *disk;
 	dialogMenuItem *menus;
+	struct disk_list *disks;
+	struct disk_info *temp;
+	struct mirror_disk *md;
 
-	disk = safe_strdup(prompt);
+	screen_clear("MIRROR");
+	disks = get_disk_list();
+	menus = safe_malloc(sizeof(*menus) * (disks->ndisks + 2));
 
+	md = safe_malloc(sizeof(*md));
+
 	i = 0;
-	menus = safe_malloc(sizeof(*menus)*MAXTYPES+2);
 	DMENUF(&menus[i++], "Next", NULL, NULL);
 	DMENUF(&menus[i++], "Back", NULL, NULL);
+	STAILQ_FOREACH(temp, &disks->list, entries) {
+		if (temp->used == 0) {
+			RDMENUFCD(&menus[i++], temp->disk,  "", &gmirror_disk_fire,
+				&gmirror_disk_checked, md);
+		}
+	}
 
-	DMENUFA(&menus[i++], "UFS", "UFS filesystem",
-		ufs_fire, FS_UFS);
-	DMENUFA(&menus[i++], "UFS+S", "UFS + soft updates",
-		ufs_fire, FS_UFS | FS_FLAGS_SOFTUPDATES);
-	DMENUFA(&menus[i++], "UFS+J", "UFS + gjournal",
-		ufs_fire, FS_UFS | FS_FLAGS_GJOURNAL);
-	DMENUFA(&menus[i++], "ZFS", "zeta filesystem",
-		zfs_fire, FS_ZFS);
-	DMENUFA(&menus[i++], "SWAP", "swap partition" ,
-		swap_fire, FS_SWAP);
-	DMENUFA(&menus[i++], "MIRROR", "gmirror a parition",
-		mirror_fire, FS_MIRROR);
+	screen_clear("MIRROR");
+	dialog_radiolist("MIRROR", "Disk Mirror",
+		7+i-2, 60, i-2, -i+2, menus+2, NULL);
 
-	screen_clear(MODULE);
-	dialog_menu(MODULE, "Please select a filesystem:",
-		17, 60, 10, -i+2, menus+2, "", NULL, NULL);
-	
-	free(disk);
-	free(menus);
-}
+	if (notnull(md->disk)) {
+		free(menus);
 
-static int
-part_fire(dialogMenuItem *self)
-{
-	switch (self->aux) {
-	case USEALL:
-		appendconfig("partition", "all");
-		dialog_partition(self->prompt);
-		break;
+		i = 0;
+		menus = safe_malloc(sizeof(*menus) * (disks->ndisks + 2));
 
-	case USENEW:
-		appendconfig("partition", "free");
-		break;
+		strcpy(md->balance, "round-robin");
+		DMENUF(&menus[i++], "Next", NULL, NULL);
+		DMENUF(&menus[i++], "Back", NULL, NULL);
+		RDMENUFCD(&menus[i++], "load",  "", &gmirror_balance_fire,
+			&gmirror_balance_checked, md);
+		RDMENUFCD(&menus[i++], "prefer",  "", &gmirror_balance_fire,
+			&gmirror_balance_checked, md);
+		RDMENUFCD(&menus[i++], "round-robin",  "", &gmirror_balance_fire,
+			&gmirror_balance_checked, md);
+		RDMENUFCD(&menus[i++], "split",  "", &gmirror_balance_fire,
+			&gmirror_balance_checked, md);
 
-	default:
-		appendconfig("partition", self->prompt);
+		screen_clear("MIRROR");
+		dialog_radiolist("MIRROR", "Mirror Balance",
+			7+i-2, 60, i-2, -i+2, menus+2, NULL);
+
+	} else {
+		free(md);
+		md = NULL;
 	}
 
-	return (0);
+	free(menus);
+	return (md);
 }
 
 int
 dialog_partsel(void *args)
 {
+	int i;
+	int status;
+	int bootloader;
 	char *buf;
 	char *token;
-	dialogMenuItem *menus;
-	int i;
-	char strfreemb[6];
-	int status;
 	char *format;
 	char prompt[1024];
-	int bootloader;
-	struct partsel *p;
+	char strfreemb[6];
+	dialogMenuItem *menus;
+	struct disk_info *di;
 
-
 	screen_clear(MODULE);
 	dialog_busy(5, 60, "Reading partition list...");
 
 	format = NULL;
-	p = (struct partsel *)args;
+	di = (struct disk_info *)args;
 
 	buf = safe_malloc(BUFSZ+1);
-	status = run_pcsysinstall(buf, BUFSZ, "disk-part", p->disk);
+	status = run_pcsysinstall(buf, BUFSZ, "disk-part", di->disk);
 	if (!strncmp(buf, "Error", 5)) {
 		free(buf);
 		return (-1);
@@ -216,9 +221,9 @@
 		}
 	}
 	
-	DMENU(&menus[i++], __DECONST(char *, p->disk), "Use entire disk",
+	DMENU(&menus[i++], __DECONST(char *, di->disk), "Use entire disk",
 		NULL, NULL, part_fire, NULL, USEALL);
-	DMENU(&menus[i++], __DECONST(char *, p->disk),
+	DMENU(&menus[i++], __DECONST(char *, di->disk),
 		"Create a new partition using free space",
 		NULL, NULL, part_fire, NULL, USENEW);
 
@@ -226,7 +231,7 @@
 	snprintf(prompt, sizeof(prompt), "The disk %s <%s>\n"
 	    "is formatted using %s and has %s free\n\n"
 	    "Please select the partition you want to use for the installation:",
-	    p->disk, p->diskname, format, strfreemb);
+	    di->disk, di->desc, format, strfreemb);
 	dialog_menu(MODULE, prompt,
 	    10+i-2, 70, i-2, -i+2, menus+2, "", NULL, NULL);
 	free(menus);
@@ -239,8 +244,24 @@
 		appendconfig("bootManager", "bsd");
 	else
 		appendconfig("bootManager", "none");
+
+	screen_clear("MIRROR");
+	if (dialog_noyes("MIRROR", "Configure Mirror?", 5, 10) == 0) {
+		struct mirror_disk *md = configure_gmirror();
+		if (md != NULL) {
+			struct disk_info *gdi;
+
+			appendconfig("mirror", md->disk);
+			appendconfig("mirrorbal", md->balance);
+
+			gdi = get_disk_info_by_disk(md->disk);
+			gdi->used = 1;
+			free(md);
+		}
+	}
+
 	appendconfig("commitDiskPart", NULL);
 
-	set_next_dialog(&dialog_label, NULL, NULL);
+	set_next_dialog("label", &dialog_label, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/rootpass.c
===================================================================
--- pcbsd-projects/txt-sysinstall/rootpass.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/rootpass.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -68,6 +68,6 @@
 
 	appendconfig("rootPass", rootPass2);
 
-	set_next_dialog(&dialog_tzone, NULL, NULL);
+	set_next_dialog("tzone", &dialog_tzone, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/txt-sysinstall.h
===================================================================
--- pcbsd-projects/txt-sysinstall/txt-sysinstall.h	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/txt-sysinstall.h	2010-08-21 00:08:09 UTC (rev 7415)
@@ -54,30 +54,88 @@
 	mptr->aux = a;		\
 } while (0) 
 
+#define RDMENU(m, p, t, c, s, f, d, a) do { \
+	dialogMenuItem *mptr = m;	\
+	mptr->prompt = p;	\
+	mptr->title  = t;	\
+	mptr->checked = c;	\
+	mptr->selected = s;	\
+	mptr->fire   = f;	\
+	mptr->data   = d;	\
+	mptr->lbra = '(';	\
+	mptr->mark = '*';	\
+	mptr->rbra = ')';	\
+	mptr->aux = a;		\
+} while (0) 
+
 #define	DMENUF(m, p, t, f) \
 	DMENU(m, p, t, NULL, NULL, f, NULL, 0)
+#define	RDMENUF(m, p, t, f) \
+	RDMENU(m, p, t, NULL, NULL, f, NULL, 0)
 
 #define	DMENUFA(m, p, t, f, a) \
 	DMENU(m, p, t, NULL, NULL, f, NULL, a)
+#define	RDMENUFA(m, p, t, f, a) \
+	RDMENU(m, p, t, NULL, NULL, f, NULL, a)
 
+#define	DMENUFDA(m, p, t, f, d, a) \
+	DMENU(m, p, t, NULL, NULL, f, d, a)
+#define	RDMENUFDA(m, p, t, f, d, a) \
+	RDMENU(m, p, t, NULL, NULL, f, d, a)
+
 #define	DMENUFC(m, p, t, f, c) \
 	DMENU(m, p, t, c, NULL, f, NULL, 0)
+#define	RDMENUFC(m, p, t, f, c) \
+	RDMENU(m, p, t, c, NULL, f, NULL, 0)
 
+#define	DMENUFCD(m, p, t, f, c, d) \
+	DMENU(m, p, t, c, NULL, f, d, 0)
+#define	RDMENUFCD(m, p, t, f, c, d) \
+	RDMENU(m, p, t, c, NULL, f, d, 0)
+
 #define	DMENUFD(m, p, t, f, d) \
 	DMENU(m, p, t, NULL, NULL, f, d, 0)
+#define	RDMENUFD(m, p, t, f, d) \
+	RDMENU(m, p, t, NULL, NULL, f, d, 0)
 
+#define	DMENUS(m, p, t, s) \
+	DMENU(m, p, t, NULL, s, NULL, NULL, 0)
+#define	RDMENUS(m, p, t, s) \
+	RDMENU(m, p, t, NULL, s, NULL, NULL, 0)
+
+#define	notnull(x)	(x != NULL && x[0] != 0)
+
 struct dialog_state {
+	char *name;
 	int (*dialog)(void *);
 	void *args;
 	void (*free_args)(void *);
 	STAILQ_ENTRY(dialog_state) entries;
 };
 
-struct partsel {
+struct disk_info {
 	char *disk;
-	char *diskname;
+	char *desc;
+	size_t ncyl;
+	size_t nhead;
+	size_t nsect;
+	size_t size;
+	char *type;
+	int used;
+	STAILQ_ENTRY(disk_info) entries;
 };
 
+struct disk_list {
+	size_t ndisks;
+	STAILQ_HEAD(diskhead, disk_info) list;
+};
+
+#ifdef	DEBUG
+#define	DISK_ARGS	"-m"
+#else
+#define	DISK_ARGS	NULL
+#endif
+
 /* dialogs */
 void		sysinstall(void);
 int			dialog_sysinstall(void *);
@@ -105,8 +163,18 @@
 char *		safe_strdup(const char *);
 int			run_pcsysinstall(char *, size_t, const char *, const char *);
 void		appendconfig(const char *, const char *);
+const char 	*getconfigval(const char *);
 void		save_config(void);
+int			b2mb(int64_t *, int64_t *);
 
+struct disk_info *get_disk_info(const char *, const char *);
+struct disk_info *get_disk_info_by_disk(const char *);
+void		free_disk_info(void *);
+
 struct dialog_state *get_next_dialog(void);
+struct dialog_state *get_dialog_by_name(const char *);
 struct dialog_state *get_prev_dialog(void);
-void set_next_dialog(int (*)(void *), void *, void (*)(void *));
+void set_next_dialog(const char *, int (*)(void *), void *, void (*)(void *));
+
+struct disk_list *get_disk_list(void);
+void	free_disk_list(void);

Modified: pcbsd-projects/txt-sysinstall/tzone.c
===================================================================
--- pcbsd-projects/txt-sysinstall/tzone.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/tzone.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -75,10 +75,12 @@
 
 		DMENUF(&menus[i++], strsep(&token, "/"), token, tzone_fire);
 	}
+
 	screen_clear(MODULE);
 	dialog_menu("Timezone selection",
 	    "Please select the time zone you are in:",
 	    20, 70, 13, -i, menus, NULL, NULL, NULL);
+
 	free(buf);
 	free(menus);
 
@@ -89,6 +91,6 @@
 		appendconfig("enableNTP", "yes");
 	}
 
-	set_next_dialog(&dialog_medium, NULL, NULL);
+	set_next_dialog("medium", &dialog_medium, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/useradd.c
===================================================================
--- pcbsd-projects/txt-sysinstall/useradd.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/useradd.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -112,6 +112,6 @@
 		}
 	}
 
-	set_next_dialog(&dialog_rootpass, NULL, NULL);
+	set_next_dialog("rootpass", &dialog_rootpass, NULL, NULL);
 	return (0);
 }

Modified: pcbsd-projects/txt-sysinstall/util.c
===================================================================
--- pcbsd-projects/txt-sysinstall/util.c	2010-08-19 17:42:52 UTC (rev 7414)
+++ pcbsd-projects/txt-sysinstall/util.c	2010-08-21 00:08:09 UTC (rev 7415)
@@ -41,6 +41,8 @@
 
 #include "txt-sysinstall.h"
 
+#define	MB	(1024 * 1024)
+
 struct config {
 	char *key;
 	char *value;
@@ -50,7 +52,9 @@
 
 STAILQ_HEAD(dialog_state_head, dialog_state) dialog_state_list;
 
+static struct disk_list DISK_LIST;
 
+
 struct dialog_state *
 get_next_dialog(void)
 {
@@ -58,6 +62,19 @@
 }
 
 struct dialog_state *
+get_dialog_by_name(const char *name)
+{
+	struct dialog_state *ds;
+
+	STAILQ_FOREACH(ds, &dialog_state_list, entries) {
+		if (strcmp(ds->name, name) == 0)
+			return (ds);
+	}
+
+	return (NULL);
+}
+
+struct dialog_state *
 get_prev_dialog(void)
 {
 	struct dialog_state *first;
@@ -73,11 +90,13 @@
 }
 
 void
-set_next_dialog(int (*next)(void *), void *args, void (*free_args)(void *))
+set_next_dialog(const char *name, int (*next)(void *),
+	void *args, void (*free_args)(void *))
 {
 	struct dialog_state *ds;
 
 	ds = safe_malloc(sizeof(*ds));
+	ds->name = safe_strdup(name);
 	ds->dialog = next;
 	ds->args = args;
 	ds->free_args = free_args;
@@ -127,7 +146,7 @@
 {
 	size_t len = 0;
 
-	if (str != NULL && str[0] != 0)
+	if (notnull(str))
 		len = strlen(str);
 
 	return (len);
@@ -139,9 +158,12 @@
 	size_t len;
 	char *copy;
 
-	len = safe_strlen(str) + 1;
-	copy = safe_malloc(len);
-	memcpy(copy, str, len);
+	copy = NULL;
+	if (notnull(str)) {
+		len = safe_strlen(str) + 1;
+		copy = safe_malloc(len);
+		memcpy(copy, str, len);
+	}
 
 	return (copy);
 }
@@ -195,7 +217,123 @@
 	return (status);
 }
 
+struct disk_info *
+get_disk_info(const char *disk, const char *desc)
+{
+	char *buf;
+	char *token;
+	struct disk_info *di;
+
+	if (disk == NULL)
+		return (NULL);
+
+	buf = safe_malloc(BUFSZ+1);
+	run_pcsysinstall(buf, BUFSZ, "disk-info", disk);
+
+	di = safe_malloc(sizeof(*di));
+	di->disk = safe_strdup(disk);
+	if (notnull(desc))
+		di->desc = safe_strdup(desc);
+
+	while ((token = strsep(&buf, "\n")) != NULL &&
+		safe_strlen(token) > 0) {
+		char *key, *val;
+
+		key =  strsep(&token, "=");
+		val = strsep(&token, ":");
+		if (strcmp(key, "cylinders") == 0)
+			di->ncyl = strtol(val, 0, 10);
+		else if (strcmp(key, "heads") == 0)
+			di->nhead = strtol(val, 0, 10);
+		else if (strcmp(key, "sectors") == 0)
+			di->nsect = strtol(val, 0, 10);
+		else if (strcmp(key, "size") == 0)
+			di->size = strtol(val, 0, 10);
+		else if (strcmp(key, "type") == 0 && notnull(val))
+			di->type = safe_strdup(val);
+		di->used = 0;
+	}
+
+	free(buf);
+	return (di);
+}
+
+struct disk_info *
+get_disk_info_by_disk(const char *disk)
+{
+	struct disk_info *di;
+
+	di = NULL;
+	STAILQ_FOREACH(di, &DISK_LIST.list, entries) {
+		if (strcmp(di->disk, disk) == 0)
+			break;
+	}
+
+	return (di);
+}
+
 void
+free_disk_info(void *args)
+{
+	struct disk_info *di = (struct disk_info *)args;
+
+	if (di != NULL) {
+		free(di->disk);
+		free(di->desc);
+		free(di->type);
+		free(di);
+	}
+}
+
+struct disk_list *
+get_disk_list(void)
+{
+	struct disk_list *ptr;
+
+	ptr = &DISK_LIST;
+	if (ptr->ndisks == 0) {
+		char *buf, *token;
+
+		buf = safe_malloc(BUFSZ+1);
+		run_pcsysinstall(buf, BUFSZ, "disk-list", DISK_ARGS);
+
+		ptr->ndisks = 0;
+		STAILQ_INIT(&ptr->list);
+
+		while ((token = strsep(&buf, "\n")) != NULL
+			&& safe_strlen(token) > 0) {
+			struct disk_info *di;
+			char *disk, *desc;
+	
+			disk = strsep(&token, ":");
+			desc = strsep(&token, ":");
+			desc += 2;
+			desc[safe_strlen(desc) - 1] = 0;
+	
+			di = get_disk_info(disk, desc);
+			STAILQ_INSERT_TAIL(&ptr->list, di, entries);
+			ptr->ndisks++;
+		}
+	}
+	
+	return (ptr);
+}
+
+
+void
+free_disk_list(void)
+{
+	struct disk_list *ptr;
+	struct disk_info *di, *temp;
+
+	ptr = &DISK_LIST;
+	STAILQ_FOREACH_SAFE(di, &ptr->list, entries, temp) {
+		STAILQ_REMOVE(&ptr->list, di, disk_info, entries);
+		free_disk_info(di);
+	}
+}
+
+void
 dialog_busy(int height, int width, const char *str)
 {
 	draw_box(stdscr, (LINES - height) / 2, (COLS - width) / 2,
@@ -212,8 +350,9 @@
 {
 	STAILQ_INIT(&configlist);
 	STAILQ_INIT(&dialog_state_list);
+	get_disk_list();
 
-	set_next_dialog(&dialog_sysinstall, NULL, NULL);
+	set_next_dialog("sysinstall", &dialog_sysinstall, NULL, NULL);
 }
 
 void
@@ -222,6 +361,8 @@
 	struct config *c, *c_temp;
 	struct dialog_state *ds, *ds_temp;
 
+	free_disk_list();
+
 	STAILQ_FOREACH_SAFE(c, &configlist, entries, c_temp) {
 		STAILQ_REMOVE(&configlist, c, config, entries);
 		free(c->key);
@@ -233,6 +374,7 @@
 		STAILQ_REMOVE(&dialog_state_list, ds, dialog_state, entries);
 		if (ds->free_args != NULL)
 			ds->free_args(ds->args);
+		free(ds->name);
 		free(ds);
 	}
 }
@@ -251,6 +393,26 @@
 	STAILQ_INSERT_TAIL(&configlist, c, entries);
 }
 
+const char *
+getconfigval(const char *key)
+{
+	const char *value;
+	struct config *c;
+
+	if (key == NULL)
+		return (NULL);
+
+	value = NULL;
+	STAILQ_FOREACH(c, &configlist, entries) {
+		if (strcmp(key, c->key) == 0) {
+			value = c->value;
+			break;
+		}
+	}
+
+	return (value);
+}
+
 void
 save_config(void)
 {
@@ -272,3 +434,19 @@
 
 	fclose(fp);
 }
+
+int
+b2mb(int64_t *b, int64_t *mb)
+{
+	if (b == NULL || mb == NULL)
+		return (-1);
+
+	if (*b >= MB)
+		*mb = *b / MB;
+	else if (*b != 0)
+		*mb = 1;
+	else
+		*mb = 0;
+	
+	return (0);
+}



More information about the Commits mailing list