From owner-svn-src-all@FreeBSD.ORG Fri Feb 18 14:54:35 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07FD5106564A; Fri, 18 Feb 2011 14:54:35 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E40A08FC19; Fri, 18 Feb 2011 14:54:34 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p1IEsYOW061542; Fri, 18 Feb 2011 14:54:34 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p1IEsYRZ061528; Fri, 18 Feb 2011 14:54:34 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201102181454.p1IEsYRZ061528@svn.freebsd.org> From: Nathan Whitehorn Date: Fri, 18 Feb 2011 14:54:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218799 - in head: etc/mtree usr.sbin usr.sbin/bsdinstall usr.sbin/bsdinstall/distextract usr.sbin/bsdinstall/distfetch usr.sbin/bsdinstall/partedit usr.sbin/bsdinstall/scripts X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Feb 2011 14:54:35 -0000 Author: nwhitehorn Date: Fri Feb 18 14:54:34 2011 New Revision: 218799 URL: http://svn.freebsd.org/changeset/base/218799 Log: Import bsdinstall. This is meant to be (eventually in conjunction with pc-sysinstall) a replacement for sysinstall in the 9.0 release and beyond. Currently supported platforms are sparc64, pc98, i386, amd64, powerpc, and powerpc64. Integration into the build system will occur in the coming weeks. Merging with pc-sysinstall will use this code as a frontend, while temporarily retaining the interactive partition editor here. This work will be done in parallel with improvements on this code and release integration. Thanks to all who have provided testing and comments! Added: head/usr.sbin/bsdinstall/ head/usr.sbin/bsdinstall/Makefile (contents, props changed) head/usr.sbin/bsdinstall/bsdinstall (contents, props changed) head/usr.sbin/bsdinstall/distextract/ head/usr.sbin/bsdinstall/distextract/Makefile (contents, props changed) head/usr.sbin/bsdinstall/distextract/distextract.c (contents, props changed) head/usr.sbin/bsdinstall/distfetch/ head/usr.sbin/bsdinstall/distfetch/Makefile (contents, props changed) head/usr.sbin/bsdinstall/distfetch/distfetch.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/ head/usr.sbin/bsdinstall/partedit/Makefile (contents, props changed) head/usr.sbin/bsdinstall/partedit/diskeditor.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/diskeditor.h (contents, props changed) head/usr.sbin/bsdinstall/partedit/gpart_ops.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/part_wizard.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit.h (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit_generic.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit_pc98.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit_powerpc.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit_sparc64.c (contents, props changed) head/usr.sbin/bsdinstall/partedit/partedit_x86.c (contents, props changed) head/usr.sbin/bsdinstall/scripts/ head/usr.sbin/bsdinstall/scripts/Makefile (contents, props changed) head/usr.sbin/bsdinstall/scripts/adduser (contents, props changed) head/usr.sbin/bsdinstall/scripts/auto (contents, props changed) head/usr.sbin/bsdinstall/scripts/config (contents, props changed) head/usr.sbin/bsdinstall/scripts/hostname (contents, props changed) head/usr.sbin/bsdinstall/scripts/jail (contents, props changed) head/usr.sbin/bsdinstall/scripts/keymap (contents, props changed) head/usr.sbin/bsdinstall/scripts/mount (contents, props changed) head/usr.sbin/bsdinstall/scripts/netconfig (contents, props changed) head/usr.sbin/bsdinstall/scripts/rootpass (contents, props changed) head/usr.sbin/bsdinstall/scripts/services (contents, props changed) head/usr.sbin/bsdinstall/scripts/time (contents, props changed) head/usr.sbin/bsdinstall/scripts/umount (contents, props changed) head/usr.sbin/bsdinstall/scripts/wlanconfig (contents, props changed) Modified: head/etc/mtree/BSD.usr.dist head/usr.sbin/Makefile Modified: head/etc/mtree/BSD.usr.dist ============================================================================== --- head/etc/mtree/BSD.usr.dist Fri Feb 18 14:34:33 2011 (r218798) +++ head/etc/mtree/BSD.usr.dist Fri Feb 18 14:54:34 2011 (r218799) @@ -32,6 +32,8 @@ .. .. libexec + bsdinstall + .. lpr ru .. Modified: head/usr.sbin/Makefile ============================================================================== --- head/usr.sbin/Makefile Fri Feb 18 14:34:33 2011 (r218798) +++ head/usr.sbin/Makefile Fri Feb 18 14:54:34 2011 (r218799) @@ -7,6 +7,7 @@ SUBDIR= adduser \ arp \ bootparamd \ burncd \ + bsdinstall \ cdcontrol \ chkgrp \ chown \ Added: head/usr.sbin/bsdinstall/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/Makefile Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +SUBDIR= distextract distfetch partedit scripts +SCRIPTS= bsdinstall + +.include Added: head/usr.sbin/bsdinstall/bsdinstall ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/bsdinstall Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,43 @@ +#!/bin/sh +#- +# Copyright (c) 2011 Nathan Whitehorn +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +: ${DISTRIBUTIONS="kernel.tgz world.tgz"}; export DISTRIBUTIONS +: ${BSDINSTALL_LOG="/tmp/bsdinstall_log"}; export BSDINSTALL_LOG +: ${BSDINSTALL_TMPETC="/tmp/bsdinstall_etc"}; export BSDINSTALL_TMPETC +: ${PATH_FSTAB="$BSDINSTALL_TMPETC/fstab"}; export PATH_FSTAB +: ${BSDINSTALL_DISTDIR="/usr/freebsd-dist"}; export BSDINSTALL_DISTDIR +: ${BSDINSTALL_CHROOT="/mnt"}; export BSDINSTALL_CHROOT + +VERB=$1; shift + +if [ -z $VERB ]; then + VERB=auto +fi + +exec /usr/libexec/bsdinstall/$VERB $@ + Added: head/usr.sbin/bsdinstall/distextract/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/distextract/Makefile Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,10 @@ +# $FreeBSD$ + +BINDIR= /usr/libexec/bsdinstall +PROG= distextract +LDADD= -larchive -lncursesw -ldialog -lm + +WARNS?= 6 +NO_MAN= true + +.include Added: head/usr.sbin/bsdinstall/distextract/distextract.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/distextract/distextract.c Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,176 @@ +/*- + * Copyright (c) 2011 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include + +static int extract_files(int nfiles, const char **files); + +int +main(void) +{ + char *diststring = strdup(getenv("DISTRIBUTIONS")); + const char **dists; + int i, retval, ndists = 0; + for (i = 0; diststring[i] != 0; i++) + if (isspace(diststring[i]) && !isspace(diststring[i+1])) + ndists++; + ndists++; /* Last one */ + + dists = calloc(ndists, sizeof(const char *)); + for (i = 0; i < ndists; i++) + dists[i] = strsep(&diststring, " \t"); + + chdir(getenv("BSDINSTALL_CHROOT")); + retval = extract_files(ndists, dists); + + free(diststring); + free(dists); + + return (retval); +} + +static int +extract_files(int nfiles, const char **files) +{ + const char *items[nfiles*2]; + char path[PATH_MAX]; + int archive_files[nfiles]; + int total_files, current_files, archive_file; + struct archive *archive; + struct archive_entry *entry; + char errormsg[512]; + char status[8]; + int i, err, progress, last_progress; + + err = 0; + progress = 0; + + /* Make the transfer list for dialog */ + for (i = 0; i < nfiles; i++) { + items[i*2] = strrchr(files[i], '/'); + if (items[i*2] != NULL) + items[i*2]++; + else + items[i*2] = files[i]; + items[i*2 + 1] = "Pending"; + } + + init_dialog(stdin, stdout); + dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); + dlg_put_backtitle(); + dialog_msgbox("", + "Checking distribution archives.\nPlease wait...", 0, 0, FALSE); + + /* Open all the archives */ + total_files = 0; + for (i = 0; i < nfiles; i++) { + archive = archive_read_new(); + archive_read_support_format_all(archive); + archive_read_support_compression_all(archive); + sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), files[i]); + err = archive_read_open_filename(archive, path, 4096); + if (err != ARCHIVE_OK) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", items[i*2], + archive_error_string(archive)); + items[i*2 + 1] = "Failed"; + dialog_msgbox("Extract Error", errormsg, 0, 0, + TRUE); + goto exit; + } + archive_files[i] = 0; + while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) + archive_files[i]++; + total_files += archive_files[i]; + archive_read_free(archive); + } + + current_files = 0; + + for (i = 0; i < nfiles; i++) { + archive = archive_read_new(); + archive_read_support_format_all(archive); + archive_read_support_compression_all(archive); + sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), files[i]); + err = archive_read_open_filename(archive, path, 4096); + + items[i*2 + 1] = "In Progress"; + archive_file = 0; + + while ((err = archive_read_next_header(archive, &entry)) == + ARCHIVE_OK) { + last_progress = progress; + progress = (current_files*100)/total_files; + + sprintf(status, "-%d", + (archive_file*100)/archive_files[i]); + items[i*2 + 1] = status; + + if (progress > last_progress) + dialog_mixedgauge("Archive Extraction", + "Extracting distribution files...", 0, 0, + progress, nfiles, + __DECONST(char **, items)); + + err = archive_read_extract(archive, entry, + ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | + ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); + + if (err != ARCHIVE_OK) + break; + + archive_file++; + current_files++; + } + + items[i*2 + 1] = "Done"; + + if (err != ARCHIVE_EOF) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", items[i*2], + archive_error_string(archive)); + items[i*2 + 1] = "Failed"; + dialog_msgbox("Extract Error", errormsg, 0, 0, + TRUE); + goto exit; + } + + archive_read_free(archive); + } + + err = 0; +exit: + end_dialog(); + + return (err); +} Added: head/usr.sbin/bsdinstall/distfetch/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/distfetch/Makefile Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,10 @@ +# $FreeBSD$ + +BINDIR= /usr/libexec/bsdinstall +PROG= distfetch +LDADD= -lfetch -lncursesw -ldialog -lm + +WARNS?= 6 +NO_MAN= true + +.include Added: head/usr.sbin/bsdinstall/distfetch/distfetch.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/distfetch/distfetch.c Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2011 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include + +static int fetch_files(int nfiles, char **urls); + +int +main(void) +{ + char *diststring = strdup(getenv("DISTRIBUTIONS")); + char **urls; + int i, nfetched, ndists = 0; + for (i = 0; diststring[i] != 0; i++) + if (isspace(diststring[i]) && !isspace(diststring[i+1])) + ndists++; + ndists++; /* Last one */ + + urls = calloc(ndists, sizeof(const char *)); + for (i = 0; i < ndists; i++) { + urls[i] = malloc(PATH_MAX); + sprintf(urls[i], "%s/%s", getenv("BSDINSTALL_DISTSITE"), + strsep(&diststring, " \t")); + } + + chdir(getenv("BSDINSTALL_DISTDIR")); + nfetched = fetch_files(ndists, urls); + + free(diststring); + for (i = 0; i < ndists; i++) + free(urls[i]); + free(urls); + + return ((nfetched == ndists) ? 0 : 1); +} + +static int +fetch_files(int nfiles, char **urls) +{ + const char **items; + FILE *fetch_out, *file_out; + struct url_stat ustat; + off_t total_bytes, current_bytes, fsize; + char status[8]; + char errormsg[512]; + uint8_t block[4096]; + size_t chunk; + int i, progress, last_progress; + int nsuccess = 0; /* Number of files successfully downloaded */ + + progress = 0; + + /* Make the transfer list for dialog */ + items = calloc(sizeof(char *), nfiles * 2); + for (i = 0; i < nfiles; i++) { + items[i*2] = strrchr(urls[i], '/'); + if (items[i*2] != NULL) + items[i*2]++; + else + items[i*2] = urls[i]; + items[i*2 + 1] = "Pending"; + } + + init_dialog(stdin, stdout); + dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); + dlg_put_backtitle(); + + dialog_msgbox("", "Connecting to server.\nPlease wait...", 0, 0, FALSE); + + /* Try to stat all the files */ + total_bytes = 0; + for (i = 0; i < nfiles; i++) { + if (fetchStatURL(urls[i], &ustat, "") == 0 && ustat.size > 0) + total_bytes += ustat.size; + } + + current_bytes = 0; + for (i = 0; i < nfiles; i++) { + last_progress = progress; + if (total_bytes == 0) + progress = (i*100)/nfiles; + + fetchLastErrCode = 0; + fetch_out = fetchXGetURL(urls[i], &ustat, ""); + if (fetch_out == NULL) { + snprintf(errormsg, sizeof(errormsg), + "Error while fetching %s: %s\n", urls[i], + fetchLastErrString); + items[i*2 + 1] = "Failed"; + dialog_msgbox("Fetch Error", errormsg, 0, 0, + TRUE); + continue; + } + + items[i*2 + 1] = "In Progress"; + fsize = 0; + file_out = fopen(items[i*2], "w+"); + if (file_out == NULL) { + snprintf(errormsg, sizeof(errormsg), + "Error while fetching %s: %s\n", + urls[i], strerror(errno)); + items[i*2 + 1] = "Failed"; + dialog_msgbox("Fetch Error", errormsg, 0, 0, + TRUE); + fclose(fetch_out); + continue; + } + + while ((chunk = fread(block, 1, sizeof(block), fetch_out)) + > 0) { + if (fwrite(block, 1, chunk, file_out) < chunk) + break; + + current_bytes += chunk; + fsize += chunk; + + if (total_bytes > 0) { + last_progress = progress; + progress = (current_bytes*100)/total_bytes; + } + + if (ustat.size > 0) { + sprintf(status, "-%jd", (fsize*100)/ustat.size); + items[i*2 + 1] = status; + } + + if (progress > last_progress) + dialog_mixedgauge("Fetching Distribution", + "Fetching distribution files...", 0, 0, + progress, nfiles, + __DECONST(char **, items)); + } + + if (ustat.size > 0 && fsize < ustat.size) { + if (fetchLastErrCode == 0) + snprintf(errormsg, sizeof(errormsg), + "Error while fetching %s: %s\n", + urls[i], strerror(errno)); + else + snprintf(errormsg, sizeof(errormsg), + "Error while fetching %s: %s\n", + urls[i], fetchLastErrString); + items[i*2 + 1] = "Failed"; + dialog_msgbox("Fetch Error", errormsg, 0, 0, + TRUE); + } else { + items[i*2 + 1] = "Done"; + nsuccess++; + } + + fclose(fetch_out); + fclose(file_out); + } + end_dialog(); + + free(items); + return (nsuccess); +} Added: head/usr.sbin/bsdinstall/partedit/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/partedit/Makefile Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,25 @@ +# $FreeBSD$ + +BINDIR= /usr/libexec/bsdinstall +PROG= partedit +LINKS= ${BINDIR}/partedit ${BINDIR}/autopart +LDADD= -lgeom -lncursesw -lutil -ldialog -lm + +PARTEDIT_ARCH= ${MACHINE} +.if ${MACHINE} == "i386" || ${MACHINE} == "amd64" +PARTEDIT_ARCH= x86 +.endif +.if ${MACHINE} == "sun4v" +PARTEDIT_ARCH= sparc64 +.endif +.if !exists(partedit_${PARTEDIT_ARCH}.c) +PARTEDIT_ARCH= generic +.endif + +SRCS= diskeditor.c partedit.c gpart_ops.c partedit_${PARTEDIT_ARCH}.c \ + part_wizard.c + +WARNS?= 3 +NO_MAN= true + +.include Added: head/usr.sbin/bsdinstall/partedit/diskeditor.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/partedit/diskeditor.c Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2011 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include + +#include "diskeditor.h" + +static void +print_partedit_item(WINDOW *partitions, struct partedit_item *items, + int item, int nscroll, int selected) +{ + chtype attr = A_NORMAL; + char sizetext[16]; + int y = item - nscroll + 1; + + wattrset(partitions, selected ? item_selected_attr : item_attr); + wmove(partitions, y, MARGIN + items[item].indentation*2); + dlg_print_text(partitions, items[item].name, 8, &attr); + wmove(partitions, y, 15); + wattrset(partitions, item_attr); + + humanize_number(sizetext, 7, items[item].size, "B", HN_AUTOSCALE, + HN_DECIMAL); + dlg_print_text(partitions, sizetext, 8, &attr); + wmove(partitions, y, 25); + dlg_print_text(partitions, items[item].type, 15, &attr); + wmove(partitions, y, 40); + if (items[item].mountpoint != NULL) + dlg_print_text(partitions, items[item].mountpoint, 8, &attr); +} + +int +diskeditor_show(const char *title, const char *cprompt, + struct partedit_item *items, int nitems, int *selected, int *nscroll) +{ + WINDOW *dialog, *partitions; + char *prompt; + const char *buttons[] = + { "Create", "Delete", "Modify", "Revert", "Auto", "Exit", NULL }; + int x, y; + int i; + int height, width, min_width; + int partlist_height, partlist_width, min_partlist_width; + int cur_scroll = 0; + int key, fkey; + int cur_button = 0, cur_part = 0; + int result = DLG_EXIT_UNKNOWN; + + static DLG_KEYS_BINDING binding[] = { + ENTERKEY_BINDINGS, + DLG_KEYS_DATA( DLGK_ENTER, ' ' ), + DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), + DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), + DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), + DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), + DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), + DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), + + SCROLLKEY_BINDINGS, + END_KEYS_BINDING + }; + + /* + * Set up editor window. + */ + prompt = dlg_strclone(cprompt); + + min_width = 50; + height = width = 0; + partlist_height = 10; + min_partlist_width = 0; + dlg_tab_correct_str(prompt); + dlg_button_layout(buttons, &min_width); + dlg_auto_size(title, prompt, &height, &width, 2, min_width); + height += partlist_height; + partlist_width = width - 2*MARGIN; + dlg_print_size(height, width); + dlg_ctl_size(height, width); + + x = dlg_box_x_ordinate(width); + y = dlg_box_y_ordinate(height); + + dialog = dlg_new_window(height, width, y, x); + dlg_register_window(dialog, "diskeditorbox", binding); + dlg_register_buttons(dialog, "diskeditorbox", buttons); + + dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + dlg_draw_bottom_box(dialog); + dlg_draw_title(dialog, title); + wattrset(dialog, dialog_attr); + + /* Partition list sub-window */ + partitions = dlg_sub_window(dialog, partlist_height, partlist_width, + y + 3, x + 1); + dlg_register_window(partitions, "partlist", binding); + dlg_register_buttons(partitions, "partlist", buttons); + wattrset(partitions, menubox_attr); + + dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, + cur_button, FALSE, width); + dlg_print_autowrap(dialog, prompt, height, width); + + if (selected != NULL) + cur_part = *selected; + if (nscroll != NULL) + cur_scroll = *nscroll; + if (cur_part - cur_scroll >= partlist_height - 2 || + cur_part - cur_scroll < 0) + cur_scroll = cur_part; + +repaint: + dlg_draw_box(dialog, 3, 1, partlist_height, partlist_width, + menubox_border_attr, menubox_attr); + for (i = cur_scroll; i < MIN(cur_scroll + partlist_height - 2, nitems); + i++) + print_partedit_item(partitions, items, i, cur_scroll, + i == cur_part); + if (nitems > partlist_height - 2) + dlg_draw_arrows(partitions, cur_scroll > 0, + nitems > cur_scroll + partlist_height - 2, + partlist_width - 5, 0, partlist_height - 1); + wrefresh(partitions); + + while (result == DLG_EXIT_UNKNOWN) { + key = dlg_mouse_wgetch(dialog, &fkey); + if ((i = dlg_char_to_button(key, buttons)) >= 0) { + cur_button = i; + dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, + cur_button, FALSE, width); + break; + } + + if (!fkey) + continue; + + switch (key) { + case DLGK_FIELD_NEXT: + cur_button = dlg_next_button(buttons, cur_button); + if (cur_button < 0) + cur_button = 0; + dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, + cur_button, FALSE, width); + break; + case DLGK_FIELD_PREV: + cur_button = dlg_prev_button(buttons, cur_button); + if (cur_button < 0) + cur_button = 0; + dlg_draw_buttons(dialog, height - 2*MARGIN, 0, buttons, + cur_button, FALSE, width); + break; + case DLGK_ITEM_NEXT: + if (cur_part == nitems - 1) + break; /* End of list */ + + /* Deselect old item */ + print_partedit_item(partitions, items, cur_part, + cur_scroll, 0); + /* Select new item */ + cur_part++; + if (cur_part - cur_scroll >= partlist_height - 2) { + cur_scroll = cur_part; + goto repaint; + } + print_partedit_item(partitions, items, cur_part, + cur_scroll, 1); + wrefresh(partitions); + break; + case DLGK_ITEM_PREV: + if (cur_part == 0) + break; /* Start of list */ + + /* Deselect old item */ + print_partedit_item(partitions, items, cur_part, + cur_scroll, 0); + /* Select new item */ + cur_part--; + if (cur_part - cur_scroll < 0) { + cur_scroll = cur_part; + goto repaint; + } + print_partedit_item(partitions, items, cur_part, + cur_scroll, 1); + wrefresh(partitions); + break; + case DLGK_PAGE_NEXT: + cur_scroll += (partlist_height - 2); + if (cur_scroll + partlist_height - 2 >= nitems) + cur_scroll = nitems - (partlist_height - 2); + if (cur_part < cur_scroll) + cur_part = cur_scroll; + goto repaint; + case DLGK_PAGE_PREV: + cur_scroll -= (partlist_height - 2); + if (cur_scroll < 0) + cur_scroll = 0; + if (cur_part >= cur_scroll + partlist_height - 2) + cur_part = cur_scroll; + goto repaint; + case DLGK_PAGE_FIRST: + cur_scroll = 0; + cur_part = cur_scroll; + goto repaint; + case DLGK_PAGE_LAST: + cur_scroll = nitems - (partlist_height - 2); + cur_part = cur_scroll; + goto repaint; + case DLGK_ENTER: + goto done; + default: + if (is_DLGK_MOUSE(key)) { + cur_button = key - M_EVENT; + dlg_draw_buttons(dialog, height - 2*MARGIN, 0, + buttons, cur_button, FALSE, width); + goto done; + } + break; + } + } + +done: + if (selected != NULL) + *selected = cur_part; + if (nscroll != NULL) + *nscroll = cur_scroll; + + dlg_del_window(partitions); + dlg_del_window(dialog); + dlg_mouse_free_regions(); + + return (cur_button); +} + Added: head/usr.sbin/bsdinstall/partedit/diskeditor.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/partedit/diskeditor.h Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2011 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _PARTEDIT_DISKEDITOR_H +#define _PARTEDIT_DISKEDITOR_H + +#include + +struct partedit_item { + int indentation; + const char *name; + intmax_t size; + const char *type; + char *mountpoint; + + void *cookie; +}; + +int diskeditor_show(const char *title, const char *prompt, + struct partedit_item *items, int nitems, int *selected, int *scroll); + +#endif Added: head/usr.sbin/bsdinstall/partedit/gpart_ops.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.sbin/bsdinstall/partedit/gpart_ops.c Fri Feb 18 14:54:34 2011 (r218799) @@ -0,0 +1,1092 @@ +/*- + * Copyright (c) 2011 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "partedit.h" + +#define GPART_FLAGS "x" /* Do not commit changes by default */ + +static void +gpart_show_error(const char *title, const char *explanation, const char *errstr) +{ + char *errmsg; + char message[512]; + int error; + + if (explanation == NULL) + explanation = ""; + + error = strtol(errstr, &errmsg, 0); + if (errmsg != errstr) { + while (errmsg[0] == ' ') + errmsg++; + if (errmsg[0] != '\0') + sprintf(message, "%s%s. %s", explanation, + strerror(error), errmsg); + else + sprintf(message, "%s%s", explanation, strerror(error)); + } else { + sprintf(message, "%s%s", explanation, errmsg); + } + + dialog_msgbox(title, message, 0, 0, TRUE); +} + +int +gpart_partition(const char *lg_name, const char *scheme) +{ + int cancel, choice; + struct gctl_req *r; + const char *errstr; + + DIALOG_LISTITEM items[] = { + {"APM", "Apple Partition Map", + "Bootable on PowerPC Apple Hardware", 0 }, + {"BSD", "BSD Labels", + "Bootable on most x86 systems", 0 }, + {"GPT", "GUID Partition Table", + "Bootable on most x86 systems", 0 }, + {"MBR", "DOS Partitions", + "Bootable on most x86 systems", 0 }, + {"PC98", "NEC PC9801 Partition Table", + "Bootable on NEC PC9801 systems", 0 }, + {"VTOC8", "Sun VTOC8 Partition Table", + "Bootable on Sun SPARC systems", 0 }, + }; + +schememenu: + if (scheme == NULL) { + dialog_vars.default_item = __DECONST(char *, default_scheme()); + cancel = dlg_menu("Partition Scheme", + "Select a partition scheme for this volume:", 0, 0, 0, + sizeof(items) / sizeof(items[0]), items, &choice, NULL); + dialog_vars.default_item = NULL; + + if (cancel) + return (-1); + + if (!is_scheme_bootable(items[choice].name)) { + char message[512]; + sprintf(message, "This partition scheme (%s) is not " + "bootable on this platform. Are you sure you want " + "to proceed?", items[choice].name); + dialog_vars.defaultno = TRUE; + cancel = dialog_yesno("Warning", message, 0, 0); + dialog_vars.defaultno = FALSE; + if (cancel) /* cancel */ + goto schememenu; + } + + scheme = items[choice].name; + } + + r = gctl_get_handle(); + gctl_ro_param(r, "class", -1, "PART"); + gctl_ro_param(r, "arg0", -1, lg_name); + gctl_ro_param(r, "flags", -1, GPART_FLAGS); + gctl_ro_param(r, "scheme", -1, scheme); + gctl_ro_param(r, "verb", -1, "create"); + + errstr = gctl_issue(r); + if (errstr != NULL && errstr[0] != '\0') { + gpart_show_error("Error", NULL, errstr); + gctl_free(r); + scheme = NULL; + goto schememenu; + } + gctl_free(r); + + if (bootcode_path(scheme) != NULL) + get_part_metadata(lg_name, 1)->bootcode = 1; + return (0); +} + +static void +gpart_activate(struct gprovider *pp) +{ + struct gconfig *gc; + struct gctl_req *r; + const char *errstr, *scheme; + const char *attribute = NULL; + intmax_t idx; + + /* + * Some partition schemes need this partition to be marked 'active' + * for it to be bootable. + */ + LIST_FOREACH(gc, &pp->lg_geom->lg_config, lg_config) { + if (strcmp(gc->lg_name, "scheme") == 0) { + scheme = gc->lg_val; + break; + } + } + + if (strcmp(scheme, "MBR") == 0 || strcmp(scheme, "EBR") == 0 || + strcmp(scheme, "PC98") == 0) + attribute = "active"; + else + return; + + LIST_FOREACH(gc, &pp->lg_config, lg_config) { + if (strcmp(gc->lg_name, "index") == 0) { + idx = atoi(gc->lg_val); + break; + } + } + + r = gctl_get_handle(); + gctl_ro_param(r, "class", -1, "PART"); + gctl_ro_param(r, "arg0", -1, pp->lg_geom->lg_name); + gctl_ro_param(r, "verb", -1, "set"); + gctl_ro_param(r, "attrib", -1, attribute); + gctl_ro_param(r, "index", sizeof(idx), &idx); + + errstr = gctl_issue(r); + if (errstr != NULL && errstr[0] != '\0') + gpart_show_error("Error", "Error marking partition active:", + errstr); + gctl_free(r); +} + +static void *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***