Index: Makefile
===================================================================
RCS file: /data/ncvs/src/usr.sbin/sysinstall/Makefile,v
retrieving revision 1.127
diff -u -r1.127 Makefile
--- Makefile	20 Oct 2002 11:16:41 -0000	1.127
+++ Makefile	2 Dec 2002 23:55:15 -0000
@@ -14,6 +14,8 @@
 SRCS+=  pccard.c
 .endif
 
+CFLAGS+= -g
+
 CFLAGS+= -I${.CURDIR}/../../gnu/lib/libdialog -I.
 CFLAGS+= -DX_AS_PKG -DUSE_GZIP=1
 .if ${MACHINE} == "pc98"
Index: install.c
===================================================================
RCS file: /data/ncvs/src/usr.sbin/sysinstall/install.c,v
retrieving revision 1.336
diff -u -r1.336 install.c
--- install.c	2 Dec 2002 20:15:16 -0000	1.336
+++ install.c	2 Dec 2002 23:36:00 -0000
@@ -50,6 +50,7 @@
 #undef MSDOSFS
 #include <sys/stat.h>
 #include <sys/sysctl.h>
+#include <limits.h>
 #include <unistd.h>
 #include <termios.h>
 
@@ -880,6 +881,44 @@
     return DITEM_SUCCESS | DITEM_RESTORE;
 }
 
+#define QUEUE_YES	1
+#define	QUEUE_NO	0
+static int
+performNewfs(PartInfo *pi, char *dname, int queue)
+{
+	char buffer[LINE_MAX];
+
+	if (pi->do_newfs) {
+		switch(pi->newfs_type) {
+		case NEWFS_UFS:
+			snprintf(buffer, LINE_MAX, "%s %s %s %s %s",
+			    NEWFS_UFS_CMD,
+			    pi->newfs_data.newfs_ufs.softupdates ?  "-U" : "",
+			    pi->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1",
+			    pi->newfs_data.newfs_ufs.user_options,
+			    dname);
+			break;
+
+		case NEWFS_MSDOS:
+			snprintf(buffer, LINE_MAX, "%s %s", NEWFS_MSDOS_CMD,
+			    dname);
+			break;
+
+		case NEWFS_CUSTOM:
+			snprintf(buffer, LINE_MAX, "%s %s",
+			    pi->newfs_data.newfs_custom.command, dname);
+			break;
+		}
+
+		if (queue == QUEUE_YES) {
+			command_shell_add(pi->mountpoint, buffer);
+			return (0);
+		} else
+			return (vsystem(buffer));
+	}
+	return (0);
+}
+
 /* Go newfs and/or mount all the filesystems we've been asked to */
 int
 installFilesystems(dialogMenuItem *self)
@@ -942,12 +981,14 @@
 	if (strcmp(root->mountpoint, "/"))
 	    msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, root->mountpoint);
 
-	if (root->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs the root partition?"))) {
+	if (root->do_newfs && (!upgrade ||
+	    !msgNoYes("You are upgrading - are you SURE you want to newfs "
+	    "the root partition?"))) {
 	    int i;
 
 	    dialog_clear_norefresh();
 	    msgNotify("Making a new root filesystem on %s", dname);
-	    i = vsystem("%s %s", root->newfs_cmd, dname);
+	    i = performNewfs(root, dname, QUEUE_NO);
 	    if (i) {
 		msgConfirm("Unable to make new root filesystem on %s!\n"
 			   "Command returned status %d", dname, i);
@@ -966,11 +1007,15 @@
 		msgConfirm("Warning: fsck returned status of %d for %s.\n"
 			   "This partition may be unsafe to use.", i, dname);
 	}
-	if (root->soft) {
+#if 0
+	if (!root->do_newfs &&
+	    root->newfs_type == NEWFS_UFS &&
+	    root->newfs_data.newf_ufs.softupdates)a {
 	    i = vsystem("tunefs -n enable %s", dname);
 	    if (i)
 		msgConfirm("Warning:  Unable to enable softupdates for root filesystem on %s", dname);
 	}
+#endif
 
 	/* Switch to block device */
 	sprintf(dname, "/dev/%s", rootdev->name);
@@ -1023,12 +1068,23 @@
 			if (c2 == rootdev)
 			    continue;
 
-			if (tmp->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c2->name)))
-			    command_shell_add(tmp->mountpoint, "%s %s/dev/%s", tmp->newfs_cmd, RunningAsInit ? "/mnt" : "", c2->name);
+			sprintf(dname, "%s/dev/%s",
+			    RunningAsInit ? "/mnt" : "", c2->name);
+
+			if (tmp->do_newfs && (!upgrade ||
+			    !msgNoYes("You are upgrading - are you SURE you"
+			    " want to newfs /dev/%s?", c2->name)))
+				performNewfs(tmp, dname, QUEUE_YES);
 			else
-			    command_shell_add(tmp->mountpoint, "fsck_ffs -y %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name);
+			    command_shell_add(tmp->mountpoint,
+				"fsck_ffs -y %s/dev/%s", RunningAsInit ?
+				"/mnt" : "", c2->name);
+#if 0
 			if (tmp->soft)
-			    command_shell_add(tmp->mountpoint, "tunefs -n enable %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name);
+			    command_shell_add(tmp->mountpoint,
+			    "tunefs -n enable %s/dev/%s", RunningAsInit ?
+			    "/mnt" : "", c2->name);
+#endif
 			command_func_add(tmp->mountpoint, Mount, c2->name);
 		    }
 		    else if (c2->type == part && c2->subtype == FS_SWAP) {
@@ -1049,7 +1105,8 @@
 		    }
 		}
 	    }
-	    else if (c1->type == fat && c1->private_data && (root->newfs || upgrade)) {
+	    else if (c1->type == fat && c1->private_data &&
+		(root->do_newfs || upgrade)) {
 		char name[FILENAME_MAX];
 
 		sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo *)c1->private_data)->mountpoint);
Index: label.c
===================================================================
RCS file: /data/ncvs/src/usr.sbin/sysinstall/label.c,v
retrieving revision 1.131
diff -u -r1.131 label.c
--- label.c	27 Nov 2002 19:46:18 -0000	1.131
+++ label.c	3 Dec 2002 01:42:11 -0000
@@ -322,35 +322,41 @@
 static PartInfo *
 new_part(char *mpoint, Boolean newfs)
 {
-    PartInfo *ret;
+    PartInfo *pi;
 
     if (!mpoint)
 	mpoint = "/change_me";
 
-    ret = (PartInfo *)safe_malloc(sizeof(PartInfo));
-    sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX);
-    strcpy(ret->newfs_cmd, "newfs ");
-    strcat(ret->newfs_cmd, variable_get(VAR_NEWFS_ARGS));
-    ret->newfs = newfs;
-    ret->soft = strcmp(mpoint, "/") ? 1 : 0;
-    return ret;
+    pi = (PartInfo *)safe_malloc(sizeof(PartInfo));
+    sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX);
+
+    pi->do_newfs = newfs;
+
+    pi->newfs_type = NEWFS_UFS;
+    strcpy(pi->newfs_data.newfs_ufs.user_options, "");
+    pi->newfs_data.newfs_ufs.acls = FALSE;
+    pi->newfs_data.newfs_ufs.multilabel = FALSE;
+    pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/");
+    pi->newfs_data.newfs_ufs.ufs2 = FALSE;
+
+    return pi;
 }
 
 #if defined(__ia64__)
 static PartInfo *
 new_efi_part(char *mpoint, Boolean newfs)
 {
-    PartInfo *ret;
+    PartInfo *pi;
 
     if (!mpoint)
 	mpoint = "/efi";
 
-    ret = (PartInfo *)safe_malloc(sizeof(PartInfo));
-    sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX);
-    /* XXX */
-    strcpy(ret->newfs_cmd, "newfs_msdos ");
-    ret->newfs = newfs;
-    ret->soft = 0;
+    pi = (PartInfo *)safe_malloc(sizeof(PartInfo));
+    sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX);
+
+    pi->do_newfs = newfs;
+    pi->newfs_type = NEWFS_MSDOS;
+
     return ret;
 }
 #endif
@@ -404,7 +410,7 @@
 
     newfs = TRUE;
     if (tmp) {
-	newfs = tmp->newfs;
+	newfs = tmp->do_newfs;
     	safe_free(tmp);
     }
     val = string_skipwhite(string_prune(val));
@@ -448,13 +454,49 @@
 static void
 getNewfsCmd(PartInfo *p)
 {
+    char buffer[NEWFS_CMD_ARGS_MAX];
     char *val;
 
-    val = msgGetInput(p->newfs_cmd,
-		      "Please enter the newfs command and options you'd like to use in\n"
-		      "creating this file system.");
-    if (val)
-	sstrncpy(p->newfs_cmd, val, NEWFS_CMD_MAX);
+    switch (p->newfs_type) {
+    case NEWFS_UFS:
+	snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s %s %s %s",
+	    NEWFS_UFS_CMD, p->newfs_data.newfs_ufs.softupdates ?  "-U" : "",
+	    p->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1",
+	    p->newfs_data.newfs_ufs.user_options);
+	break;
+    case NEWFS_MSDOS:
+	snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s", NEWFS_MSDOS_CMD);
+	break;
+    case NEWFS_CUSTOM:
+	strcpy(buffer, p->newfs_data.newfs_custom.command);
+	break;
+    }
+
+    val = msgGetInput(buffer,
+	"Please enter the newfs command and options you'd like to use in\n"
+	"creating this file system.");
+    if (val != NULL) {
+	p->newfs_type = NEWFS_CUSTOM;
+	strlcpy(p->newfs_data.newfs_custom.command, val, NEWFS_CMD_ARGS_MAX);
+    }
+}
+
+static void
+getNewfsOptionalArguments(PartInfo *p)
+{
+	char buffer[NEWFS_CMD_ARGS_MAX];
+	char *val;
+
+	/* Must be UFS, per argument checking in I/O routines. */
+
+	strlcpy(buffer,  p->newfs_data.newfs_ufs.user_options,
+	    NEWFS_CMD_ARGS_MAX);
+	val = msgGetInput(buffer,
+	    "Please enter any additional UFS newfs options you'd like to\n"
+	    "use in creating this file system.");
+	if (val != NULL)
+		strlcpy(p->newfs_data.newfs_ufs.user_options, val,
+		    NEWFS_CMD_ARGS_MAX);
 }
 
 #define MAX_MOUNT_NAME	9
@@ -473,7 +515,7 @@
 static void
 print_label_chunks(void)
 {
-    int  i, j, srow, prow, pcol;
+    int  i, len, j, spaces, srow, prow, pcol;
     int  sz;
     char clrmsg[80];
     int ChunkPartStartRow;
@@ -581,7 +623,7 @@
 	}
 	/* Otherwise it's a DOS, swap or filesystem entry in the Chunk window */
 	else {
-	    char onestr[PART_OFF], num[10], *mountpoint, newfs[10];
+	    char onestr[PART_OFF], num[10], *mountpoint, newfs[12];
 
 	    /*
 	     * We copy this into a blank-padded string so that it looks like
@@ -631,13 +673,37 @@
 #endif
 	    }
 	    else if (label_chunk_info[i].c->private_data && label_chunk_info[i].type == PART_FILESYSTEM) {
-		strcpy(newfs, "UFS");
-		strcat(newfs,
-		    ((PartInfo *)label_chunk_info[i].c->private_data)->soft ?
-		      "+S" : "  ");
-		strcat(newfs,
-		    ((PartInfo *)label_chunk_info[i].c->private_data)->newfs ?
-		      " Y" : " N");
+		PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data;
+
+		switch (pi->newfs_type) {
+		case NEWFS_UFS:
+			len = 0;
+			strcpy(newfs, "UFS");
+			if (pi->newfs_data.newfs_ufs.softupdates ||
+			    pi->newfs_data.newfs_ufs.ufs2)
+				strcat(newfs, "+");
+			else
+				len++;
+			if (pi->newfs_data.newfs_ufs.softupdates)
+				strcat(newfs, "S");
+			else
+				len++;
+			if (pi->newfs_data.newfs_ufs.ufs2)
+				strcat(newfs, "2");
+			else
+				len++;
+			for (spaces = 0; spaces < len; spaces++)
+				strcat(newfs, " ");
+
+			break;
+		case NEWFS_MSDOS:
+			strcpy(newfs, "FAT");
+			break;
+		case NEWFS_CUSTOM:
+			strcpy(newfs, "CST");
+			break;
+		}
+		strcat(newfs, pi->do_newfs ? " Y" : " N ");
 	    }
 	    else if (label_chunk_info[i].type == PART_SWAP)
 		strcpy(newfs, "SWAP");
@@ -799,6 +865,27 @@
 	    clear_wins();
 	    break;
 
+	case '2':
+	    if (label_chunk_info[here].type == PART_FILESYSTEM) {
+		PartInfo *pi =
+		    ((PartInfo *)label_chunk_info[here].c->private_data);
+
+		if ((pi != NULL) &&
+		    (pi->newfs_type == NEWFS_UFS)) {
+#ifdef __i386__
+			if (label_chunk_info[here].c->flags & CHUNK_IS_ROOT)
+				msg = MSG_NOT_APPLICABLE;
+			else
+#endif
+				pi->newfs_data.newfs_ufs.ufs2 =
+				    !pi->newfs_data.newfs_ufs.ufs2;
+		} else
+		    msg = MSG_NOT_APPLICABLE;
+	    } else
+		msg = MSG_NOT_APPLICABLE;
+	    break;
+		break;
+
 	case 'A':
 	    if (label_chunk_info[here].type != PART_SLICE) {
 		msg = "You can only do this in a disk slice (at top of screen)";
@@ -987,7 +1074,7 @@
 		p = get_mountpoint(label_chunk_info[here].c);
 		if (p) {
 		    if (!oldp)
-		    	p->newfs = FALSE;
+		    	p->do_newfs = FALSE;
 		    if (label_chunk_info[here].type == PART_FAT
 			&& (!strcmp(p->mountpoint, "/") || !strcmp(p->mountpoint, "/usr")
 			    || !strcmp(p->mountpoint, "/var"))) {
@@ -1009,8 +1096,9 @@
 
 	case 'N':	/* Set newfs options */
 	    if (label_chunk_info[here].c->private_data &&
-		((PartInfo *)label_chunk_info[here].c->private_data)->newfs)
-		getNewfsCmd(label_chunk_info[here].c->private_data);
+		((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs)
+		getNewfsOptionalArguments(
+		    label_chunk_info[here].c->private_data);
 	    else
 		msg = MSG_NOT_APPLICABLE;
 	    clear_wins();
@@ -1019,8 +1107,10 @@
 	case 'S':	/* Toggle soft updates flag */
 	    if (label_chunk_info[here].type == PART_FILESYSTEM) {
 		PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data);
-		if (pi)
-		    pi->soft = !pi->soft;
+		if (pi != NULL &&
+		    pi->newfs_type == NEWFS_UFS)
+			pi->newfs_data.newfs_ufs.softupdates =
+			    !pi->newfs_data.newfs_ufs.softupdates;
 		else
 		    msg = MSG_NOT_APPLICABLE;
 	    }
@@ -1032,15 +1122,20 @@
 	    if ((label_chunk_info[here].type == PART_FILESYSTEM) &&
 	        (label_chunk_info[here].c->private_data)) {
 		PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data);
-		if (!pi->newfs)
+		if (!pi->do_newfs)
 		    label_chunk_info[here].c->flags |= CHUNK_NEWFS;
 		else
 		    label_chunk_info[here].c->flags &= ~CHUNK_NEWFS;
 
 		label_chunk_info[here].c->private_data =
-		    new_part(pi ? pi->mountpoint : NULL, pi ? !pi->newfs : TRUE);
-		if (pi && pi->soft)
-		    ((PartInfo *)label_chunk_info[here].c->private_data)->soft = 1;
+		    new_part(pi ? pi->mountpoint : NULL, pi ? !pi->do_newfs
+		    : TRUE);
+		if (pi != NULL &&
+		    pi->newfs_type == NEWFS_UFS) {
+		    PartInfo *pi_new = label_chunk_info[here].c->private_data;
+
+		    pi_new->newfs_data.newfs_ufs = pi->newfs_data.newfs_ufs;
+		}
 		safe_free(pi);
 		label_chunk_info[here].c->private_free = safe_free;
 		if (variable_cmp(DISK_LABELLED, "written"))
@@ -1050,14 +1145,16 @@
 	    else if (label_chunk_info[here].type == PART_FAT &&
 	      label_chunk_info[here].c->type == efi &&
 	      label_chunk_info[here].c->private_data) {
-		PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data);
-		if (!pi->newfs)
+		PartInfo *pi =
+		    ((PartInfo *)label_chunk_info[here].c->private_data);
+
+		if (!pi->do_newfs)
 		    label_chunk_info[here].c->flags |= CHUNK_NEWFS;
 		else
 		    label_chunk_info[here].c->flags &= ~CHUNK_NEWFS;
 
 		label_chunk_info[here].c->private_data =
-		    new_efi_part(pi->mountpoint, !pi->newfs);
+		    new_efi_part(pi->mountpoint, !pi->do_newfs);
 		safe_free(pi);
 		label_chunk_info[here].c->private_free = safe_free;
 		if (variable_cmp(DISK_LABELLED, "written"))
@@ -1113,6 +1210,16 @@
 	    clear_wins();
 	    break;
 
+	case 'Z':	/* Set newfs command line */
+	    if (label_chunk_info[here].c->private_data &&
+		((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs)
+		getNewfsCmd(label_chunk_info[here].c->private_data);
+	    else
+		msg = MSG_NOT_APPLICABLE;
+	    clear_wins();
+	    break;
+
+
 	case '|':
 	    if (!msgNoYes("Are you sure you want to go into Wizard mode?\n\n"
 			  "This is an entirely undocumented feature which you are not\n"
@@ -1437,9 +1544,10 @@
 			status = DITEM_FAILURE;
 			break;
 		    } else {
-			tmp->private_data = new_part(mpoint, TRUE);
+			PartInfo *pi;
+			pi = tmp->private_data = new_part(mpoint, TRUE);
 			tmp->private_free = safe_free;
-			((PartInfo *)tmp->private_data)->soft = soft;
+			pi->newfs_data.newfs_ufs.softupdates = soft;
 		    }
 		}
 	    }
@@ -1459,7 +1567,7 @@
 		newfs = toupper(do_newfs[0]) == 'Y' ? TRUE : FALSE;
 		if (c1->private_data) {
 		    p = c1->private_data;
-		    p->newfs = newfs;
+		    p->do_newfs = newfs;
 		    strcpy(p->mountpoint, mpoint);
 		}
 		else {
Index: sysinstall.h
===================================================================
RCS file: /data/ncvs/src/usr.sbin/sysinstall/sysinstall.h,v
retrieving revision 1.235
diff -u -r1.235 sysinstall.h
--- sysinstall.h	2 Dec 2002 20:15:16 -0000	1.235
+++ sysinstall.h	3 Dec 2002 00:06:23 -0000
@@ -308,14 +308,39 @@
     PART_FAT,
 } PartType;
 
-/* The longest newfs command we'll hand to system() */
-#define NEWFS_CMD_MAX	256
+#define	NEWFS_UFS_CMD		"newfs"
+#define	NEWFS_MSDOS_CMD		"newfs_msdos"
+
+enum newfs_type { NEWFS_UFS, NEWFS_MSDOS, NEWFS_CUSTOM };
+#define	NEWFS_UFS_STRING	"UFS"
+#define	NEWFS_MSDOS_STRING	"FAT"
+#define	NEWFS_CUSTOM_STRING	"CST"
+
+/* The longest set of custom command line arguments we'll pass. */
+#define NEWFS_CMD_ARGS_MAX	256
 
 typedef struct _part_info {
-    Boolean newfs;
-    char mountpoint[FILENAME_MAX];
-    char newfs_cmd[NEWFS_CMD_MAX];
-    int soft;
+	char mountpoint[FILENAME_MAX];
+
+	/* Is invocation of newfs desired? */
+	Boolean do_newfs;
+
+	enum newfs_type newfs_type;
+	union {
+		struct {
+			char user_options[NEWFS_CMD_ARGS_MAX];
+			Boolean acls;		/* unused */
+			Boolean multilabel;	/* unused */
+			Boolean softupdates;
+			Boolean ufs2;
+		} newfs_ufs;
+		struct {
+			/* unused */
+		} newfs_msdos;
+		struct {
+			char command[NEWFS_CMD_ARGS_MAX];
+		} newfs_custom;
+	} newfs_data;
 } PartInfo;
 
 /* An option */
Index: help/partition.hlp
===================================================================
RCS file: /data/ncvs/src/usr.sbin/sysinstall/help/partition.hlp,v
retrieving revision 1.8
diff -u -r1.8 partition.hlp
--- help/partition.hlp	11 Mar 2001 04:24:52 -0000	1.8
+++ help/partition.hlp	3 Dec 2002 01:38:28 -0000
@@ -126,6 +126,33 @@
 policy results in free'd blocks not being "garbage collected" as fast
 as they're being requested.
 
+To make use of UFS2, press '2' on a UFS file system to toggle the
+on-disk format revision.  UFS2 provides native support for extended
+attributes, larger disk sizes, and forward compatibility with new
+on-disk high performance directory layout and storage extents.
+However, UFS2 is unsupported on versions of FreeBSD prior to 5.0,
+so it is not recommended for environments requiring backward
+compatibility.  Also, UFS2 is not currently recommended as a root
+file system format for non-64-bit platforms due to increased size
+of the boot loader; special local configuration is required to boot
+UFS2 as a root file system on i386 and PC98.
+
+To add additional flags to the newfs command line for UFS file
+systems, press 'N'.  These options will be specified before the
+device argument of the command line, but after any other options
+placed there by sysinstall, such as the UFS version and soft
+updates flag; as such, arguments provided may override existing
+settings.  To completely replace the newfs command used by
+sysinstall, press 'Z' to convert a partition to a Custom
+partition type.  Sysinstall will prompt you with the newfs
+command line that it would have used based on existing settings
+prior to the change, but allow you to modify any aspect of the
+command line.  Once a partition has been converted to a custom
+partition in the label editor, you will need to restart the
+labeling process or delete and recreate the partition to restore
+it to a non-custom state.  Custom partitions are represented by
+the letters "CST" instead of "UFS" or "FAT.
+
 When you're done, type `Q' to exit.
 
 No actual changes will be made to the disk until you (C)ommit from the
