--- /dev/null
+src/backend/lua/200_install.lua
+src/backend/lua/400_configure.lua
+src/backend/lua/600_upgrade.lua
+src/backend/lua/800_netboot.lua
+src/backend/lua/conf/cmdnames.lua
+src/backend/lua/conf/def_pkgs.lua
+src/backend/lua/configure/100_choose_where_from.lua
+src/backend/lua/configure/200_select_disk.lua
+src/backend/lua/configure/300_select_part.lua
+src/backend/lua/configure/400_mount_target_system.lua
+src/backend/lua/configure/500_menu.lua
+src/backend/lua/configure/600_unmount_target_system.lua
+src/backend/lua/configure/main.lua
+src/backend/lua/configure/menu/100_set_root_password.lua
+src/backend/lua/configure/menu/200_add_user.lua
+src/backend/lua/configure/menu/300_set_timezone.lua
+src/backend/lua/configure/menu/350_set_datetime.lua
+src/backend/lua/configure/menu/400_change_console_settings.lua
+src/backend/lua/configure/menu/500_install_packages.lua
+src/backend/lua/configure/menu/550_remove_packages.lua
+src/backend/lua/configure/menu/main.lua
+src/backend/lua/conf/mountpoints.lua
+src/backend/lua/conf/sources.lua
+src/backend/lua/install/100_welcome.lua
+src/backend/lua/install/200_select_disk.lua
+src/backend/lua/install/250_partition_disk.lua
+src/backend/lua/install/270_install_bootblocks.lua
+src/backend/lua/install/300_select_part.lua
+src/backend/lua/install/400_select_subparts.lua
+src/backend/lua/install/450_select_packages.lua
+src/backend/lua/install/500_install_os.lua
+src/backend/lua/install/700_install_bootblocks.lua
+src/backend/lua/install/800_finished.lua
+src/backend/lua/install/900_reboot.lua
+src/backend/lua/install/main.lua
+src/backend/lua/lib/Bitwise.lua
+src/backend/lua/lib/Capacity.lua
+src/backend/lua/lib/CmdChain.lua
+src/backend/lua/lib/ConfigFile.lua
+src/backend/lua/lib/configvars.lua
+src/backend/lua/lib/Disk.lua
+src/backend/lua/lib/Flow.lua
+src/backend/lua/lib/FlowStep.lua
+src/backend/lua/lib/fsm.lua
+src/backend/lua/lib/Installation.lua
+src/backend/lua/lib/MenuItem.lua
+src/backend/lua/lib/Menu.lua
+src/backend/lua/lib/mountpoint.lua
+src/backend/lua/lib/Network.lua
+src/backend/lua/lib/PackageGraph.lua
+src/backend/lua/lib/PackageList.lua
+src/backend/lua/lib/Package.lua
+src/backend/lua/lib/PackageSet.lua
+src/backend/lua/lib/Partition.lua
+src/backend/lua/lib/storage.lua
+src/backend/lua/lib/StorageSystem.lua
+src/backend/lua/lib/StorageSystemUI.lua
+src/backend/lua/lib/StorageUI.lua
+src/backend/lua/lib/Subpartition.lua
+src/backend/lua/lib/target_system.lua
+src/backend/lua/main.lua
+src/backend/lua/Makefile
+src/backend/lua/netboot/500_setup_server.lua
+src/backend/lua/netboot/main.lua
+src/backend/lua/pit/100_select_language.lua
+src/backend/lua/pit/800_configure_network.lua
+src/backend/lua/pit/main.lua
+src/backend/lua/po/dfuibe_lua.pot
+src/backend/lua/po/ru.po
+src/backend/lua/scripts/test/apptest.lua
+src/backend/lua/scripts/test/bitwise.lua
+src/backend/lua/scripts/test/clock.lua
+src/backend/lua/scripts/test/commands.lua
+src/backend/lua/scripts/test/configvars.lua
+src/backend/lua/scripts/test/dfui.lua
+src/backend/lua/scripts/test/expander.lua
+src/backend/lua/scripts/test/filesystem.lua
+src/backend/lua/scripts/test/fsm/final.lua
+src/backend/lua/scripts/test/fsm.lua
+src/backend/lua/scripts/test/fsm/main.lua
+src/backend/lua/scripts/test/fsm/middle.lua
+src/backend/lua/scripts/test/fsm/start.lua
+src/backend/lua/scripts/test/fsm/subfsm.lua
+src/backend/lua/scripts/test/fsm/subfsm/main.lua
+src/backend/lua/scripts/test/fsm/subfsm/one.lua
+src/backend/lua/scripts/test/fsm/subfsm/two.lua
+src/backend/lua/scripts/test/main.lua
+src/backend/lua/scripts/test/menu/010_first.lua
+src/backend/lua/scripts/test/menu/020_second.lua
+src/backend/lua/scripts/test/menu/030_third.lua
+src/backend/lua/scripts/test/menu/500_submenu/010_first.lua
+src/backend/lua/scripts/test/menu/500_submenu.lua
+src/backend/lua/scripts/test/menu/500_submenu/main.lua
+src/backend/lua/scripts/test/menu.lua
+src/backend/lua/scripts/test/menu/main.lua
+src/backend/lua/scripts/test/network.lua
+src/backend/lua/scripts/test/pipe.lua
+src/backend/lua/scripts/test/progress.lua
+src/backend/lua/scripts/test/pty.lua
+src/backend/lua/scripts/test/storage.lua
+src/backend/lua/scripts/test/wait_for.lua
+src/backend/lua/upgrade/200_select_disk.lua
+src/backend/lua/upgrade/300_select_part.lua
+src/backend/lua/upgrade/400_mount_target_system.lua
+src/backend/lua/upgrade/500_perform_upgrade.lua
+src/backend/lua/upgrade/600_unmount_target_system.lua
+src/backend/lua/upgrade/main.lua
+++ /dev/null
--- $Id: 200_install.lua,v 1.7 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-
-return {
- name = _("Install %s", App.os.name),
- short_desc = _("Install %s on this computer system", App.os.name),
- effect = function()
- App.descend("install")
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 400_configure.lua,v 1.4 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-
-return {
- name = _("Configure an Installed System"),
- short_desc = _("Configure a %s OS that has already been installed", App.os.name),
- effect = function()
- App.descend("configure")
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 600_upgrade.lua,v 1.1 2005/03/27 23:19:29 cpressey Exp $
-
-return {
- name = _("Upgrade an Installed System"),
- short_desc = _("Upgrade a system with to the newest available version"),
- effect = function()
- App.descend("upgrade")
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 800_netboot.lua,v 1.1 2005/03/27 01:46:09 cpressey Exp $
-
-return {
- name = _("Set up NetBoot Server"),
- short_desc = _("Make this computer a boot server " ..
- "for other machines on the network"),
- effect = function()
- App.descend("netboot")
- return Menu.CONTINUE
- end
-}
+++ /dev/null
-# BSD Makefile for dfuibe_lua.
-# $Id: Makefile,v 1.42 2005/04/05 20:53:46 cpressey Exp $
-
-PACKAGE= dfuibe_lua
-
-.if defined(WITH_NLS)
-LOCALEDIR= /usr/local/share/locale
-LANGUAGES= ru
-.endif
-
-all:
- @echo "No building required."
-
-# XXX this will probably be a little nightmarish to do right...
-in_cvs: all
-
-clean:
- rm -rf so/*.so po/*.mo
-
-pot:
- cat `find . -name '*.lua' ! -regex '\./scripts/test/main.lua'` | \
- sed 's|\-\-|//|' | sed 's/\.\.//' | \
- xgettext -s -C --no-location --keyword=_ -o po/${PACKAGE}.pot -
+++ /dev/null
--- Example command names conf file for dfuibe_lua backend.
--- $Id: cmdnames.lua,v 1.8 2005/03/27 23:15:43 cpressey Exp $
-
-local cmd_names = {
- SH = "bin/sh",
- MKDIR = "bin/mkdir",
- CHMOD = "bin/chmod",
- LN = "bin/ln",
- RM = "bin/rm",
- CP = "bin/cp",
- DATE = "bin/date",
- ECHO = "bin/echo",
- DD = "bin/dd",
- MV = "bin/mv",
- CAT = "bin/cat",
- TEST = "bin/test",
- TEST_DEV = "bin/test -c",
- CPDUP = "bin/cpdup -o -vvv -I",
-
- ATACONTROL = "sbin/atacontrol",
- MOUNT = "sbin/mount",
- MOUNT_MFS = "sbin/mount_mfs",
- UMOUNT = "sbin/umount",
- SWAPON = "sbin/swapon",
- DISKLABEL = "sbin/disklabel",
- NEWFS = "sbin/newfs",
- NEWFS_MSDOS = "sbin/newfs_msdos",
- FDISK = "sbin/fdisk",
- DUMPON = "sbin/dumpon",
- IFCONFIG = "sbin/ifconfig",
- ROUTE = "sbin/route",
- DHCLIENT = "sbin/dhclient",
- SYSCTL = "sbin/sysctl",
-
- TOUCH = "usr/bin/touch",
- YES = "usr/bin/yes",
- BUNZIP2 = "usr/bin/bunzip2",
- GREP = "usr/bin/grep",
- KILLALL = "usr/bin/killall",
- BASENAME = "usr/bin/basename",
- SORT = "usr/bin/sort",
- COMM = "usr/bin/comm",
- AWK = "usr/bin/awk",
- SED = "usr/bin/sed",
- BC = "usr/bin/bc",
- TR = "usr/bin/tr",
- FIND = "usr/bin/find",
- CHFLAGS = "usr/bin/chflags",
- XARGS = "usr/bin/xargs",
-
- PWD_MKDB = "usr/sbin/pwd_mkdb",
- CHROOT = "usr/sbin/chroot",
- VIDCONTROL = "usr/sbin/vidcontrol",
- KBDCONTROL = "usr/sbin/kbdcontrol",
- PW = "usr/sbin/pw",
- SWAPINFO = "usr/sbin/swapinfo",
- BOOT0CFG = "usr/sbin/boot0cfg",
- FDFORMAT = "usr/sbin/fdformat",
- MTREE = "usr/sbin/mtree",
- INETD = "usr/sbin/inetd",
- DHCPD = "usr/sbin/dhcpd",
- RPCBIND = "usr/sbin/rpcbind",
- MOUNTD = "usr/sbin/mountd",
- NFSD = "usr/sbin/nfsd",
-
- PKG_ADD = "usr/sbin/pkg_add",
- PKG_DELETE = "usr/sbin/pkg_delete",
- PKG_CREATE = "usr/sbin/pkg_create",
- PKG_INFO = "usr/sbin/pkg_info",
-
- TFTPD = "usr/libexec/tftpd",
-
- CVSUP = "usr/local/bin/cvsup",
- MEMTEST = "usr/local/bin/memtest",
-
- -- These aren't commands, but they're configurable here nonetheless.
-
- DMESG_BOOT = "var/run/dmesg.boot"
-}
-
-if App.os.name == "OpenBSD" then
- cmd_names.TEST_DEV = "bin/test -b"
-end
-
-if App.os.name ~= "DragonFly" then
- cmd_names.CPDUP = "usr/local/bin/cpdup -o -vvv"
-end
-
-return cmd_names
+++ /dev/null
--- $Id: def_pkgs.lua,v 1.2 2005/02/24 23:08:03 cpressey Exp $
-
--- Default packages to install during the install phase.
-
--- Note that these packages are specified by Lua regular expressions
--- that will be passed to string.find(). This allows us to specify
--- packages regardless of their version number, etc.
-
-return {
- "^cdrtools-",
- "^cvsup-"
-}
+++ /dev/null
--- $Id: mountpoints.lua,v 1.4 2005/02/24 23:08:03 cpressey Exp $
-
--- Default configuration file for suggested mountpoints.
---
--- Note that this file should return a function which takes two
--- numbers (the capacity of the partition and the capacity of
--- RAM, both in megabytes) and should return a list of tables,
--- each like:
---
--- {
--- mountpoint = "/foo", -- name of mountpoint
--- capstring = "123M" -- suggested capacity
--- }
---
--- Note that the capstring can be "*" to indicate 'use the
--- rest of the partition.')
-
-return function(part_cap, ram_cap)
-
- --
- -- First, calculate suggested swap size:
- --
- local swap = 2 * ram_cap
- if ram_cap > (part_cap / 2) or part_cap < 4096 then
- swap = ram_cap
- end
- swap = tostring(swap) .. "M"
-
- --
- -- Now, based on the capacity of the partition,
- -- return an appropriate list of suggested mountpoints.
- --
- if part_cap < 523 then
- return {
- { mountpoint = "/", capstring = "70M" },
- { mountpoint = "swap", capstring = swap },
- { mountpoint = "/var", capstring = "32M" },
- { mountpoint = "/tmp", capstring = "32M" },
- { mountpoint = "/usr", capstring = "174M" },
- { mountpoint = "/home", capstring = "*" }
- }
- elseif part_cap < 1024 then
- return {
- { mountpoint = "/", capstring = "96M" },
- { mountpoint = "swap", capstring = swap },
- { mountpoint = "/var", capstring = "64M" },
- { mountpoint = "/tmp", capstring = "64M" },
- { mountpoint = "/usr", capstring = "256M" },
- { mountpoint = "/home", capstring = "*" }
- }
- elseif part_cap < 4096 then
- return {
- { mountpoint = "/", capstring = "128M" },
- { mountpoint = "swap", capstring = swap },
- { mountpoint = "/var", capstring = "128M" },
- { mountpoint = "/tmp", capstring = "128M" },
- { mountpoint = "/usr", capstring = "512M" },
- { mountpoint = "/home", capstring = "*" }
- }
- elseif part_cap < 10240 then
- return {
- { mountpoint = "/", capstring = "256M" },
- { mountpoint = "swap", capstring = swap },
- { mountpoint = "/var", capstring = "256M" },
- { mountpoint = "/tmp", capstring = "256M" },
- { mountpoint = "/usr", capstring = "3G" },
- { mountpoint = "/home", capstring = "*" }
- }
- else
- return {
- { mountpoint = "/", capstring = "256M" },
- { mountpoint = "swap", capstring = swap },
- { mountpoint = "/var", capstring = "256M" },
- { mountpoint = "/tmp", capstring = "256M" },
- { mountpoint = "/usr", capstring = "8G" },
- { mountpoint = "/home", capstring = "*" }
- }
- end
-end
+++ /dev/null
--- $Id: sources.lua,v 1.3 2005/02/24 23:08:03 cpressey Exp $
-
--- Default configuration file for source objects (files and directories)
--- to copy to the HDD during the install.
-
--- Note that this conf file should return list of strings - each string
--- is a filename, without any leading root directory specified, which
--- will be copied to the HDD during install.
-
--- Note that if you (for example) do not want to copy /usr/local/share,
--- you will need to specify all subdirs of /usr/local except for share
--- in this list.
-
-return {
- "COPYRIGHT",
- "bin",
- "boot",
- "cdrom",
- "dev",
- "etc",
- "libexec",
- "lib",
- "kernel",
- "modules",
- "root",
- "sbin",
- "sys",
- "tmp",
- "usr/bin",
- "usr/games",
- "usr/include",
- "usr/lib",
--- "usr/local", -- we should use mtree to generate the hier for
--- "usr/X11R6", -- these, then use pkg_add to populate them.
- "usr/libdata",
- "usr/libexec",
- "usr/obj",
- "usr/sbin",
- "usr/share",
- "usr/src",
- "var"
-}
+++ /dev/null
--- $Id: 100_choose_where_from.lua,v 1.3 2005/02/24 23:08:03 cpressey Exp $
-
-require "target_system"
-
-return {
- name = "choose_target_system",
- title = "Choose Target System",
- action = function(fsm)
- local action_id = App.ui:present({
- id = "choose_target_system",
- name = _("Choose Target System"),
- short_desc = _(
- "Please choose which installed system you want to configure."
- ),
- actions = {
- {
- id = "this",
- name = _("Configure the Running System")
- },
- {
- id = "disk",
- name = _("Configure a System on Disk")
- },
- {
- id = "cancel",
- name = _("Cancel"),
- }
- },
- role = "menu"
- }).action_id
-
- if action_id == "cancel" then
- return nil
- end
-
- if action_id == "disk" then
- return fsm:next()
- end
-
- App.state.target = TargetSystem.new()
- App.state.target:use_current()
-
- -- Jump straight to the menu.
- return "configuration_menu"
- end
-}
+++ /dev/null
--- $Id: 200_select_disk.lua,v 1.5 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-require "storage_ui"
-
-return {
- name = "select_disk",
- title = "Select Disk",
- action = function(fsm)
- App.state.sel_disk = nil
- App.state.sel_part = nil
-
- -- XXX there might be a better place to handle this.
- if App.state.storage:get_disk_count() == 0 then
- App.ui:inform(_(
- "The installer could not find any suitable disks " ..
- "attached to this computer. If you wish to " ..
- "configure an installation of %s " ..
- "on an unorthodox storage device, you will have to " ..
- "exit to a LiveCD command prompt and configure it " ..
- "manually, using the file /README as a guide.",
- App.os.name)
- )
- return nil
- end
-
- local dd = StorageUI.select_disk({
- sd = App.state.storage,
- short_desc = _(
- "Select the disk on which the installation of %s " ..
- "that you wish to configure resides.",
- App.os.name),
- cancel_desc = _("Return to Main") -- _("Return to %s", fsm:prev().title)
- })
-
- if dd then
- App.state.sel_disk = dd
- return fsm:next()
- else
- return nil -- fsm:prev()
- end
- end
-}
+++ /dev/null
--- $Id: 300_select_part.lua,v 1.4 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-require "storage_ui"
-
-return {
- name = "select_part",
- title = "Select Partition",
- action = function(fsm)
- App.state.sel_part = nil
-
- local pd = StorageUI.select_part({
- dd = App.state.sel_disk,
- short_desc = _(
- "Select the primary partition of %s " ..
- "on which the installation of %s resides.",
- App.state.sel_disk:get_name(),
- App.os.name),
- cancel_desc = _("Return to %s", fsm:prev().title)
- })
-
- if pd then
- App.state.sel_part = pd
- return fsm:next()
- else
- return fsm:prev()
- end
- end
-}
+++ /dev/null
--- $Id: 400_mount_target_system.lua,v 1.13 2005/02/24 23:08:03 cpressey Exp $
-
-require "target_system"
-
-return {
- name = "mount_target_system",
- title = "Mount Target System",
- action = function(fsm)
- --
- -- If there is a target system mounted, unmount it before starting.
- --
- if App.state.target ~= nil and App.state.target:is_mounted() then
- if not App.state.target:unmount() then
- App.ui:inform(
- _("Warning: already-mounted target system could " ..
- "not be correctly unmounted first.")
- )
- return fsm:prev()
- end
- end
-
- App.state.target = TargetSystem.new(App.state.sel_part, "mnt")
- if not App.state.target:probe() then
- App.ui:inform(_(
- "The target system could not be successfully probed."
- ))
- return fsm:prev()
- end
- if not App.state.target:mount() then
- App.ui:inform(_(
- "The target system could not be successfully mounted."
- ))
- return fsm:prev()
- end
-
- return fsm:next()
- end
-}
+++ /dev/null
--- $Id: 500_menu.lua,v 1.4 2005/02/24 23:08:03 cpressey Exp $
-
-require "dfui"
-
-return {
- name = "configuration_menu",
- title = "Configuration Menu",
- action = function(fsm)
- App.descend("menu")
- return fsm:next()
- end
-}
+++ /dev/null
--- $Id: 600_unmount_target_system.lua,v 1.4 2005/02/24 23:08:03 cpressey Exp $
-
-require "target_system"
-
-return {
- name = "unmount_target_system",
- title = "Unmount Target System",
- action = function(fsm)
- if App.state.target:unmount() then
- return fsm:next()
- else
- App.ui:inform("Target system could not be unmounted!")
- return nil
- end
- end
-}
+++ /dev/null
--- demo/configure/main.lua
--- $Id: main.lua,v 1.6 2005/02/24 23:08:03 cpressey Exp $
--- Main segment of the demonstration configurator.
-
-require "fsm"
-
-FSM.auto("choose_target_system")
+++ /dev/null
--- $Id: 100_set_root_password.lua,v 1.6 2005/03/29 18:00:18 den Exp $
-
-require "gettext"
-
-local set_root_password = function()
- local done = false
- local result
- local cmds
- local form = {
- id = "root_passwd",
- name = _("Set Root Password"),
- short_desc = _(
- "Here you can set the super-user (root) password."
- ),
-
- fields = {
- {
- id = "root_passwd_1",
- name = _("Root Password"),
- short_desc = _("Enter the root password you would like to use"),
- obscured = "true"
- },
- {
- id = "root_passwd_2",
- name = _("Re-type Root Password"),
- short_desc = _("Enter the same password again to confirm"),
- obscured = "true"
- }
- },
-
- actions = {
- {
- id = "ok",
- name = _("Accept and Set Password")
- },
- {
- id = "cancel",
- name = _("Return to Configure Menu")
- }
- },
-
- datasets = {
- { root_passwd_1 = "", root_passwd_2 = "" }
- }
- }
-
- while not done do
- result = App.ui:present(form)
-
- if result.action_id == "ok" then
- form.datasets = result.datasets
-
- --
- -- Fetch form field values.
- --
-
- local root_passwd_1 = result.datasets[1].root_passwd_1
- local root_passwd_2 = result.datasets[1].root_passwd_2
-
- --[[
- if (!assert_clean(a->c, _("Root Password"), root_passwd_1, PW_NOT_ALLOWED)) {
- done = 0;
- ]]--
-
- if root_passwd_1 == root_passwd_2 then
- --
- -- Passwords match, so set the root password.
- --
- cmds = CmdChain.new()
- App.state.target:cmds_set_password(cmds,
- "root", root_passwd_1)
- if cmds:execute() then
- App.ui:inform(
- _("The root password has been changed.")
- )
- done = true
- else
- App.ui:inform(
- _("An error occurred when " ..
- "setting the root password.")
- )
- done = false
- end
- else
- --
- -- Passwords don't match - tell the user, let them try again.
- --
- App.ui:inform(
- _("The passwords do not match.")
- )
- done = false
- end
- else
- -- Cancelled
- done = true
- end
- end
-end
-
-return {
- name = _("Set Root Password"),
- effect = function()
- set_root_password()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 200_add_user.lua,v 1.7 2005/03/29 12:12:15 den Exp $
-
-require "gettext"
-
-local is_gecos_clean = function(gecos)
- local i, char
-
- i = 1
- while i <= string.len(gecos) do
- char = string.sub(gecos, i, i)
- if string.find(char, "%c") or -- no ctrl chars
- string.byte(char) == 127 or -- no 'DEL' char
- string.find(":!@", char, 1, true) then -- none of these
- return false
- end
- i = i + 1
- end
-
- return true
-end
-
-local is_name_clean = function(name)
- local i, char
-
- i = 1
- while i <= string.len(name) do
- char = string.sub(name, i, i)
- if string.find(char, "%c") or -- no ctrl chars
- string.byte(char) == 127 or -- no 'DEL' char
- string.byte(char) > 127 or -- no 8-bit chars
- -- and none of these:
- string.find(" ,\t:+&#%^()!@~*?<>=|\\/\"", char, 1, true) or
- (char == "-" and i == 1) or -- no '-' at start
- -- '$' only at end:
- (char == "$" and i ~= string.len(name)) then
- return false
- end
- i = i + 1
- end
-
- return true
-end
-
-local add_user = function()
- local done = false
- local result
- local cmds
-
- local form = {
- id = "add_user",
- name = _("Add User"),
- short_desc = _("Here you can add a user to an installed system.\n\n" ..
- "You can leave the Home Directory, User ID, and Login Group " ..
- "fields empty if you want these items to be automatically " ..
- "allocated by the system."),
- fields = {
- {
- id = "username",
- name = _("Username"),
- short_desc = _("Enter the username the user will log in as")
- },
- {
- id = "gecos",
- name = _("Real Name"),
- short_desc = _("Enter the real name (or GECOS field) of this user")
- },
- {
- id = "passwd_1",
- name = _("Password"),
- short_desc = _("Enter the user's password (will not be displayed)"),
- obscured = "true"
- },
- {
- id = "passwd_2",
- name = _("Password (Again)"),
- short_desc = _("Re-enter the user's password to confirm"),
- obscured = "true"
- },
- {
- id = "shell",
- name = _("Shell"),
- short_desc = _("Enter the full path to the user's shell program")
- },
- {
- id = "home",
- name = _("Home Directory"),
- short_desc = _("Enter the full path to the user's home directory, or leave blank")
- },
- {
- id = "uid",
- name = _("User ID"),
- short_desc = _("Enter this account's numeric user id, or leave blank")
- },
- {
- id = "group",
- name = _("Login Group"),
- short_desc = _("Enter the primary group for this account, or leave blank")
- },
- {
- id = "groups",
- name = _("Other Group Memberships"),
- short_desc = _(
- "Enter a comma-separated list of other groups " ..
- "that this user should belong to"
- )
- }
- },
- actions = {
- {
- id = "ok",
- name = _("Accept and Add User")
- },
- {
- id = "cancel",
- name = _("Return to Configure Menu")
- }
- },
- datasets = {
- {
- username = "",
- gecos = "",
- passwd_1 = "",
- passwd_2 = "",
- shell = "/bin/tcsh",
- home = "",
- uid = "",
- group = "",
- groups = ""
- }
- }
- }
-
- while not done do
- result = App.ui:present(form)
- if result.action_id == "ok" then
- form.datasets = result.datasets
-
- --
- -- Fetch form field values.
- --
- local username = result.datasets[1].username
- local gecos = result.datasets[1].gecos
- local passwd_1 = result.datasets[1].passwd_1
- local passwd_2 = result.datasets[1].passwd_2
- local shell = result.datasets[1].shell
- local home = result.datasets[1].home
- local uid = result.datasets[1].uid
- local group = result.datasets[1].group
- local groups = result.datasets[1].groups
-
- --
- -- Valid field values.
- --
-
- if string.len(username) == 0 then
- App.ui:inform(_(
- "You must enter a username."
- ))
- elseif passwd_1 ~= passwd_2 then
- App.ui:inform(_(
- "The passwords do not match."
- ))
- elseif not is_name_clean(username) then
- App.ui:inform(_(
- "The username contains illegal characters."
- ))
- elseif not is_gecos_clean(gecos) then
- App.ui:inform(_(
- "The text specified in the Real Name " ..
- "field contains illegal characters."
- ))
- elseif not is_name_clean(group) then
- App.ui:inform(_(
- "The name of the login group contains " ..
- "illegal characters."
- ))
- --[[
- !assert_clean(a->c, _("Home Directory"), home, FILENAME_NOT_ALLOWED) ||
- !assert_clean(a->c, _("User ID"), uid, PW_NOT_ALLOWED) ||
- !assert_clean(a->c, _("Group Memberships"), groups, MEMBERSHIPS_NOT_ALLOWED)) {
- done = 0;
- ]]--
- elseif not FileSystem.is_program(App.dir.root .. shell) and
- shell ~= "/nonexistent" then
- App.ui:inform(_(
- "The selected shell does not exist on the system."
- ))
- else
- local cmds = CmdChain.new()
-
- App.state.target:cmds_add_user(cmds, {
- username = username,
- gecos = gecos,
- shell = shell,
- uid = uid,
- group = group,
- home = home,
- groups = groups,
- password = passwd_1
- })
- if cmds:execute() then
- App.ui:inform(_(
- "User `%s' was added.",
- username
- ))
- done = true
- else
- App.ui:inform(_(
- "User was not successfully added."
- ))
- end
- end
- else
- -- Cancelled.
- done = true
- end
- end
-end
-
-return {
- name = _("Add User"),
- effect = function()
- add_user()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 300_set_timezone.lua,v 1.3 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-
-local set_timezone = function()
- local cmds, files, dir, filename, full_filename, found_file
-
- if App.ui:present({
- id = "internal_clock_type",
- name = _("Local or UTC (Greenwich Mean Time) clock"),
- short_desc = _(
- "Is this machine's internal clock set to local time " ..
- "or UTC (Universal Coordinated Time, roughly the same " ..
- "as Greenwich Mean Time)?\n\n" ..
- "If you don't know, assume local time for now."
- ),
-
- actions = {
- {
- id = "local",
- name = _("Local Time")
- },
- {
- id = "utc",
- name = _("UTC Time")
- }
- }
- }).action_id == "utc" then
- cmds = CmdChain.new()
-
- cmds:add({
- cmdline = "${root}${TOUCH} ${root}${base}etc/wall_cmos_clock",
- replacements = {
- base = App.state.target:get_base()
- }
- })
- cmds:execute()
- end
-
- --
- -- Select a file.
- --
- dir = App.expand("${root}${base}usr/share/zoneinfo",
- {
- base = App.state.target:get_base()
- }
- )
-
- found_file = false
- while not found_file do
- filename = App.ui:select_file{
- title = _("Select Time Zone"),
- short_desc = _("Select a Time Zone appropriate to your physical location."),
- cancel_desc = _("Return to Utilities Menu"),
- dir = dir
- }
- if filename == "cancel" then
- return false
- end
- full_filename = dir .. "/" .. filename
- if FileSystem.is_dir(full_filename) then
- dir = full_filename
- else
- filename = full_filename
- found_file = true
- end
- end
-
- cmds = CmdChain.new()
- cmds:add({
- cmdline = "${root}${CP} ${filename} ${root}${base}etc/localtime",
- replacements = {
- filename = filename,
- base = App.state.target:get_base()
- }
- })
- if cmds:execute() then
- App.ui:inform(_(
- "The Time Zone has been successfully set to %s.",
- filename
- ))
- end
-end
-
-return {
- name = _("Set Timezone"),
- effect = function()
- set_timezone()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 350_set_datetime.lua,v 1.2 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-
-local set_datetime = function()
- local cmds, date_tab, form, response
-
- date_tab = os.date("*t")
-
- form = {
- id = "set_datetime",
- name = _("Set Time and Date"),
- short_desc = _(
- "Enter the current date and time of day to set " ..
- "this computer's internal timekeeping clock."
- ),
-
- fields = {
- {
- id = "year",
- name = _("Year"),
- short_desc = _("Enter the current year (e.g. `2004')")
- },
- {
- id = "month",
- name = _("Month"),
- short_desc = _("Enter the current month (e.g. `07')")
- },
- {
- id = "day",
- name = _("Day"),
- short_desc = _("Enter the current day of month (e.g. `30')")
- },
- {
- id = "hour",
- name = _("Hour"),
- short_desc = _("Enter the current hour (e.g. `07')")
- },
- {
- id = "min",
- name = _("Minute"),
- short_desc = _("Enter the current minute (e.g. `59')")
- }
- },
-
- datasets = {
- {
- year = tostring(date_tab.year),
- month = tostring(date_tab.month),
- day = tostring(date_tab.day),
- hour = tostring(date_tab.hour),
- min = tostring(date_tab.min)
- }
- },
-
- actions = {
- {
- id = "ok",
- name = _("OK")
- },
- {
- id = "cancel",
- name = _("Cancel")
- }
- }
- }
-
- while not done do
- response = App.ui:present(form)
- if response.action_id ~= "ok" then
- return false
- end
-
- date_tab = {
- year = tonumber(response.datasets[1].year),
- month = tonumber(response.datasets[1].month),
- day = tonumber(response.datasets[1].day),
- hour = tonumber(response.datasets[1].hour),
- min = tonumber(response.datasets[1].min)
- }
-
- --
- -- Validate the given date and time.
- --
-
- if date_tab.year > 0 and
- date_tab.month >= 1 and date_tab.month <= 12 and
- date_tab.day >= 1 and date_tab.day <= 31 and
- date_tab.hour >= 0 and date_tab.hour <= 23 and
- date_tab.min >= 0 and date_tab.min <= 59 then
-
- cmds = CmdChain.new()
- cmds:add("${root}${DATE} -n " .. string.format(
- "%04d%02d%02d%02d%02d",
- date_tab.year,
- date_tab.month,
- date_tab.day,
- date_tab.hour,
- date_tab.min
- ))
- if cmds:execute() then
- App.ui:inform(_(
- "The time and date have successfully been set."
- ))
- done = true
- else
- App.ui:inform(_(
- "An error occurred while attempting to set " ..
- "time and date."
- ))
- end
- else
- App.ui:inform(_(
- "Please enter numbers within acceptable ranges " ..
- "for year, month, day of month, hour, and minute."
- ))
- end
- end
-
- return true
-end
-
-return {
- name = _("Set Time and Date"),
- effect = function()
- set_datetime()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 400_change_console_settings.lua,v 1.2 2005/02/24 23:08:03 cpressey Exp $
-
-require "gettext"
-
-local set_keyboard_map = function()
- local cmds, files, dir, filename, full_filename
-
- --
- -- Select a file.
- --
- dir = App.expand("${root}${base}usr/share/syscons/keymaps",
- {
- base = App.state.target:get_base()
- }
- )
-
- filename = App.ui:select_file{
- title = _("Select Keyboard Map"),
- short_desc = _(
- "Select a keyboard map appropriate to your keyboard layout."
- ),
- cancel_desc = _("Return to Utilities Menu"),
- dir = dir,
- extension = "kbd"
- }
- if filename == "cancel" then
- return false
- end
- filename = dir .. "/" .. filename
-
- cmds = CmdChain.new()
- cmds:add{
- cmdline = "${root}${KBDCONTROL} -l ${filename} < /dev/ttyv0",
- replacements = { filename = filename }
- }
- if cmds:execute() then
- --[[
- snprintf(filename, 256, "/usr/share/syscons/keymaps/%s", s);
- snprintf(keymapname, 256, filename_noext(basename(filename)));
- config_var_set(rc_conf, "keymap", keymapname);
- ]]--
-
- return true
- else
- App.ui:inform(_(
- "Errors occurred; keyboard map was not successfully set."
- ))
- end
-end
-
-local set_video_font = function()
- local cmds, files, dir, filename, full_filename
-
- --
- -- Select a file.
- --
- dir = App.expand("${root}${base}usr/share/syscons/fonts",
- {
- base = App.state.target:get_base()
- }
- )
-
- filename = App.ui:select_file{
- title = _("Select Console Font"),
- short_desc = _("Select a font appropriate to your video monitor and language."),
- cancel_desc = _("Return to Utilities Menu"),
- dir = dir,
- extension = "fnt"
- }
- if filename == "cancel" then
- return false
- end
- filename = dir .. "/" .. filename
-
- cmds = CmdChain.new()
- cmds:add{
- cmdline = "${root}${VIDCONTROL} -f ${filename} < /dev/ttyv0",
- replacements = { filename = filename }
- }
- if cmds:execute() then
- local found, len, w, h = string.find(filename, "(%d+)x(%d+)")
- if found then
- w = tonumber(w)
- h = tonumber(h)
- --[[
- snprintf(variable, 256, "font8x%d", by);
- snprintf(filename, 256, "/usr/share/syscons/fonts/%s", s);
- snprintf(fontname, 256, filename_noext(basename(filename)));
- config_var_set(rc_conf, variable, fontname);
- ]]--
- end
-
- return true
- else
- App.ui:inform(_(
- "Errors occurred; video font was not successfully set."
- ))
- end
-end
-
-
-local set_screen_map = function()
- local cmds, files, dir, filename, full_filename
-
- --
- -- Select a file.
- --
- dir = App.expand("${root}${base}usr/share/syscons/scrnmaps",
- {
- base = App.state.target:get_base()
- }
- )
-
- filename = App.ui:select_file{
- title = _("Select Screen Map"),
- short_desc = _(
- "Select a mapping for translating characters as they " ..
- "appear on your video console screen."
- ),
- cancel_desc = _("Return to Utilities Menu"),
- dir = dir,
- extension = "scm"
- }
- if filename == "cancel" then
- return false
- end
- filename = dir .. "/" .. filename
-
- cmds = CmdChain.new()
- cmds:add{
- cmdline = "${root}${VIDCONTROL} -l ${filename} < /dev/ttyv0",
- replacements = { filename = filename }
- }
- if cmds:execute() then
- --[[
- snprintf(filename, 256, "/usr/share/syscons/scrnmaps/%s", s);
- snprintf(scrnmapname, 256, filename_noext(basename(filename)));
- config_var_set(rc_conf, "scrnmap", scrnmapname);
- ]]--
-
- return true
- else
- App.ui:inform(_(
- "Errors occurred; screen map was not successfully set."
- ))
- end
-end
-
-return {
- name = _("Change Console Settings"),
- effect = function()
- if set_video_font() and set_screen_map() and set_keyboard_map() then
- -- everything was set.
- -- XXX write to rc.conf ?
- end
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 500_install_packages.lua,v 1.7 2005/04/04 20:38:50 cpressey Exp $
-
-require "cmdchain"
-require "package"
-require "storage_ui"
-
-local num_keys = function(tab)
- local k, v
- local i = 0
- for k, v in tab do i = i + 1 end
- return i
-end
-
-local install_packages = function()
- local base = App.state.target:get_base()
- local pkg_list = Package.list_all("")
- local ok, i, pkg_name, selected
- local sel_pkgs = {}
-
- for i, pkg_name in pkg_list do
- if not Package.exists(base, pkg_name) then
- sel_pkgs[pkg_name] = false -- but present...
- end
- end
-
- ok, sel_pkgs = StorageUI.select_packages{
- name = _("Select Packages"),
- short_desc = _("Select the packages you wish to install from " ..
- "the LiveCD onto the HDD."),
- checkbox_name = _("Install?"),
- ok_name = _("Install these Packages"),
- cancel_name = _("Cancel"),
-
- sel_pkgs = sel_pkgs
- }
-
- if ok then
- local cmds = CmdChain.new()
- local pkg_seen = {}
- local pkg_done = {}
- local pkg_extra = ""
- local n, i = 0, 0
- local pr = App.ui:new_progress_bar{
- title = _("Calculating package dependencies...")
- }
-
- for pkg_name, selected in sel_pkgs do
- if selected then
- n = n + 1
- end
- end
-
- pr:start()
- for pkg_name, selected in sel_pkgs do
- if selected then
- Package.cmds_copy(
- base, cmds, pkg_name, pkg_seen, pkg_done
- )
- i = i + 1
- pr:set_amount((i * 100) / n)
- pr:update()
- end
- end
- pr:stop()
-
- for pkg_name, selected in pkg_seen do
- if not sel_pkgs[pkg_name] then
- pkg_extra = pkg_extra .. pkg_name .. "\n"
- end
- end
-
- if pkg_extra ~= "" then
- if not App.ui:confirm(_(
- "The following packages are required to " ..
- "support the packages you selected, and " ..
- "will also be installed:\n\n%s\n" ..
- "Is this acceptable?", pkg_extra
- )) then
- return
- end
- end
-
- if cmds:execute() then
- App.ui:inform(_(
- "%d/%d packages were successfully installed!",
- num_keys(pkg_done), num_keys(pkg_seen)
- ))
- else
- App.ui:inform(_(
- "Errors occurred while installing packages. " ..
- "Some packages may not have been " ..
- "successfully installed."
- ))
- end
- end
-end
-
-return {
- name = _("Install Packages"),
- effect = function()
- install_packages()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: 550_remove_packages.lua,v 1.7 2005/04/04 20:38:50 cpressey Exp $
-
-require "cmdchain"
-require "package"
-require "storage_ui"
-
-local num_keys = function(tab)
- local k, v
- local i = 0
- for k, v in tab do i = i + 1 end
- return i
-end
-
-local remove_packages = function()
- local base = App.state.target:get_base()
- local pkg_list = Package.list_all(base)
- local ok, i, pkg_name, selected
- local sel_pkgs = {}
-
- if table.getn(pkg_list) == 0 then
- App.ui:inform(_(
- "There are no packages installed on this system."
- ))
- return
- end
-
- for i, pkg_name in pkg_list do
- sel_pkgs[pkg_name] = false -- but present...
- end
-
- ok, sel_pkgs = StorageUI.select_packages{
- name = _("Select Packages"),
- short_desc = _("Select the packages you wish to remove from " ..
- "this system"),
- checkbox_name = _("Remove?"),
- ok_name = _("Remove these Packages"),
- cancel_name = _("Cancel"),
-
- sel_pkgs = sel_pkgs
- }
-
- if ok then
- local cmds = CmdChain.new()
- local pkg_seen = {}
- local pkg_done = {}
- local pkg_extra = ""
- local n, i = 0, 0
- local pr = App.ui:new_progress_bar{
- title = _("Calculating package dependencies...")
- }
-
- for pkg_name, selected in sel_pkgs do
- if selected then
- n = n + 1
- end
- end
-
- pr:start()
- for pkg_name, selected in sel_pkgs do
- if selected then
- Package.cmds_remove(
- base, cmds, pkg_name, pkg_seen, pkg_done
- )
- i = i + 1
- pr:set_amount((i * 100) / n)
- pr:update()
- end
- end
- pr:stop()
-
- for pkg_name, selected in pkg_seen do
- if not sel_pkgs[pkg_name] then
- pkg_extra = pkg_extra .. pkg_name .. "\n"
- end
- end
-
- if pkg_extra ~= "" then
- if not App.ui:confirm(_(
- "The following installed packages require " ..
- "one or more of the packages you selected, " ..
- "and will also be removed:\n\n%s\n" ..
- "Is this acceptable?", pkg_extra
- )) then
- return
- end
- end
-
- if cmds:execute() then
- App.ui:inform(_(
- "%d/%d packages were successfully removed!",
- num_keys(pkg_done), num_keys(pkg_seen)
- ))
- else
- App.ui:inform(_(
- "There were errors. " ..
- "Some packages may not have been " ..
- "successfully removed."
- ))
- end
- end
-end
-
-return {
- name = _("Remove Packages"),
- effect = function()
- remove_packages()
- return Menu.CONTINUE
- end
-}
+++ /dev/null
--- $Id: main.lua,v 1.3 2005/02/24 23:08:04 cpressey Exp $
-
-Menu.auto{
- name = _("Select Component to Configure"),
- short_desc = _("Choose one of the following things to configure.")
-}
+++ /dev/null
--- $Id: 100_welcome.lua,v 1.7 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-
-return {
- name = "welcome",
- title = "Welcome",
- action = function(fsm)
- return App.ui:present({
- id = "begin_install",
- name = _("Begin Installation"),
- short_desc = _(
- "This experimental application will install %s" ..
- " on one of the hard disk drives attached to this computer. " ..
- "It has been designed to make it easy to install " ..
- "%s in the typical case. " ..
- "If you have special requirements that are not addressed " ..
- "by this installer, or if you have problems using it, you " ..
- "are welcome to install %s manually. " ..
- "To do so select Exit to Live CD, login as root, and follow " ..
- "the instructions given in the file /README ." ..
- "\n\n" ..
- "NOTE! As with any installation process, YOU ARE " ..
- "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS " ..
- "COMPUTER BEFORE PROCEEDING!",
- App.os.name, App.os.name, App.os.name),
- long_desc = _(
- "Some situations in which you might not wish to use this " ..
- "installer are:\n\n" ..
- "- you want to install %s onto a " ..
- "logical/extended partition;\n" ..
- "- you want to install %s " ..
- "onto a ``dangerously dedicated'' disk; or\n" ..
- "- you want full and utter control over the install process.",
- App.os.name, App.os.name),
-
- actions = {
- {
- id = "proceed",
- name = _("Install %s", App.os.name),
- effect = function()
- return fsm:next()
- end
- },
- {
- id = "cancel",
- name = _("Return to Previous Menu"),
- effect = function()
- return nil
- end
- }
- }
- }).result
- end
-}
+++ /dev/null
--- $Id: 200_select_disk.lua,v 1.16 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-require "storage_ui"
-
-return {
- name = "select_disk",
- title = "Select Disk",
- action = function(fsm)
- App.state.sel_disk = nil
- App.state.sel_part = nil
-
- -- XXX there might be a better place to handle this.
- if App.state.storage:get_disk_count() == 0 then
- App.ui:inform(_(
- "The installer could not find any disks suitable " ..
- "for installation (IDE or SCSI) attached to this " ..
- "computer. If you wish to install %s" ..
- " on an unorthodox storage device, you will have to " ..
- "exit to a LiveCD command prompt and install it " ..
- "manually, using the file /README as a guide.",
- App.os.name)
- )
- return nil
- end
-
- local dd = StorageUI.select_disk({
- sd = App.state.storage,
- short_desc = _("Select a disk on which to install %s.",
- App.os.name),
- cancel_desc = _("Return to %s", fsm:prev().title)
- })
-
- if dd then
- if dd:is_mounted() then
- App.ui:inform(
- _("One or more subpartitions of one or more " ..
- "primary partitions of the selected disk " ..
- "are already in use (they are currently " ..
- "mounted on mountpoints in the filesystem.) " ..
- "You should either unmount them before " ..
- "proceeding, or select a different disk to " ..
- "install %s on.", App.os.name))
- return fsm:current()
- end
-
- App.state.sel_disk = dd
-
- -- XXX there might be a better place to handle this.
- if dd:get_capacity() < App.state.disk_min then
- App.ui:inform(_(
- "WARNING: you should have a disk " ..
- "at least %dM in size, or " ..
- "you may encounter problems trying to " ..
- "install %s.",
- App.state.disk_min, App.os.name)
- )
- end
-
- return fsm:next()
- else
- return fsm:prev()
- end
- end
-}
+++ /dev/null
--- $Id: 250_partition_disk.lua,v 1.21 2005/03/31 12:35:50 den Exp $
-
-require "gettext"
-
-local datasets_list = nil
-
-local name_to_sysid_map = {
- ["DragonFly/FreeBSD"] = 165,
- ["OpenBSD"] = 166,
- ["NetBSD"] = 169,
- ["MS-DOS"] = 15,
- ["Linux"] = 131,
- ["Plan9"] = 57
-}
-
-local options_list = {}
-local sysid_to_name_map = {}
-local k, v
-for k, v in name_to_sysid_map do
- table.insert(options_list, k)
- sysid_to_name_map[v] = k
-end
-
-local populate_from_disk = function(dd)
- local pd
- local list = {}
-
- local toyn = function(bool)
- if bool then
- return "Y"
- else
- return "N"
- end
- end
-
- for pd in dd:get_parts() do
- table.insert(list, {
- capstring = StorageDescriptor.format_capstring(pd:get_size()),
- sysid = sysid_to_name_map[pd:get_sysid()] or
- tostring(pd:get_sysid()),
- active = toyn(pd:is_active())
- })
- end
-
- return list
-end
-
-local populate_one_big_partition = function(dd)
- return {
- {
- capstring = "*",
- sysid = "165",
- active = "Y"
- }
- }
-end
-
-local edit_partitions = function(fsm)
- if not datasets_list then
- datasets_list = populate_from_disk(App.state.sel_disk)
- end
-
- local fields_list = {
- {
- id = "capstring",
- name = _("Capacity")
- },
- {
- id = "sysid",
- name = _("Partition Type"),
- options = options_list,
- editable = "false"
- },
- {
- id = "active",
- name = _("Active?"),
- control = "checkbox"
- }
- }
-
- local actions_list = {
- {
- id = "ok",
- name = _("Accept and Create"),
- },
- {
- id = "cancel",
- name = _("Return to %s", fsm:prev().title),
- }
- }
-
- local response = App.ui:present({
- id = "edit_partitions",
- name = _("Edit Partitions"),
- short_desc = _("Select the partitions (also known " ..
- "as `slices' in BSD tradition) you want to " ..
- "have on this disk.\n\n" ..
- "For Capacity, use 'M' to indicate megabytes, 'G' to " ..
- "indicate gigabytes, or a single '*' to indicate " ..
- "'use the remaining space on the disk'."),
- special = "bsdinstaller_edit_partitions",
- minimum_width = "64",
-
- actions = actions_list,
- fields = fields_list,
- datasets = datasets_list,
-
- multiple = "true",
- extensible = "true"
- })
-
- -- remember these subpartition selections in case we come back here.
- datasets_list = response.datasets
-
- return response.action_id == "ok"
-end
-
-local check_datasets = function(dd, list)
- local i, dataset
- local size
- local disk_size = dd:get_raw_size()
- local used_size = 60 -- initial offset
- local wildcard_size = false
-
- for i, dataset in list do
- if (name_to_sysid_map[dataset.sysid] or tonumber(dataset.sysid)) == 0 then
- App.ui:inform(_(
- "'%s' is not a recognized partition type. " ..
- "Please use a numeric identifier if you " ..
- "wish to use an unlisted partition type.",
- dataset.sysid
- ))
- return false
- end
-
- if dataset.capstring == "*" then
- if wildcard_size then
- App.ui:inform(_(
- "Only one partition may have a " ..
- "capacity of '*'."
- ))
- return false
- end
- wildcard_size = true
- end
-
- size = StorageDescriptor.parse_capstring(dataset.capstring, 0)
- if not size then
- App.ui:inform(_(
- "Capacity must either end in 'M' " ..
- "for megabytes, 'G' for gigabytes, " ..
- "or be '*' to indicate 'use all " ..
- "remaining space.'"
- ))
- return false
- end
-
- used_size = used_size + size
- end
-
- if used_size > disk_size then
- if not App.ui:confirm(_(
- "WARNING: The total number of sectors needed " ..
- "for the requested partitions (%d) exceeds the " ..
- "number of sectors available on the disk (%d) " ..
- "by %d sectors (%s.)\n\n" ..
- "This is an invalid configuration; we " ..
- "recommend shrinking the size of one or " ..
- "more partitions before proceeding.\n\n" ..
- "Proceed anyway?",
- used_size, disk_size, used_size - disk_size,
- StorageDescriptor.format_capstring(used_size - disk_size))) then
- return false
- end
- end
-
- if used_size < disk_size - App.state.max_waste and
- not wildcard_size then
- if not App.ui:confirm(_(
- "Note: the total number of sectors needed " ..
- "for the requested partitions (%d) does not make " ..
- "full use of the number of sectors available " ..
- "on the disk (%d.) There will be %d unused " ..
- "sectors (%s.)\n\n" ..
- "You may wish to expand one or more partitions " ..
- "before proceeding.\n\n" ..
- "Proceed anyway?",
- used_size, disk_size, disk_size - used_size,
- StorageDescriptor.format_capstring(disk_size - used_size))) then
- return false
- end
- end
-
- return true
-end
-
---
--- This assumes check_datasets has already been called.
---
-local create_partitions_from_datasets = function(dd, list)
- local i, dataset
- local part_no = 1
- local offset = 60
- local disk_size = dd:get_raw_size()
- local used_size = offset
- local size
- local sysid
-
- dd:clear_parts()
-
- for i, dataset in list do
- used_size = used_size +
- StorageDescriptor.parse_capstring(dataset.capstring, 0)
- end
-
- for i, dataset in list do
- size = StorageDescriptor.parse_capstring(dataset.capstring,
- disk_size - used_size)
-
- dd:add_part(PartitionDescriptor.new{
- parent = dd,
- number = part_no,
- start = offset,
- size = size,
- sysid = name_to_sysid_map[dataset.sysid] or tonumber(dataset.sysid),
- active = (dataset.active == "Y")
- })
-
- offset = offset + size
- part_no = part_no + 1
- end
-
- return true
-end
-
-local do_edit_partitions = function(fsm)
- if edit_partitions(fsm) then
- local cmds = CmdChain.new()
-
- if check_datasets(App.state.sel_disk, datasets_list) and
- create_partitions_from_datasets(
- App.state.sel_disk, datasets_list) then
-
- App.state.sel_disk:cmds_partition(cmds)
- cmds:execute()
-
- -- refresh our knowledge of the storage
- App.state.sel_disk, App.state.sel_part =
- App.state.storage:resurvey(
- App.state.sel_disk, App.state.sel_part
- )
-
- -- Mark this disk as having been 'touched'
- -- (modified destructively, i.e. partitioned)
- -- by us.
- if App.state.sel_disk then
- App.state.sel_disk:touch()
- end
-
- return fsm:next()
- else
- return fsm:current()
- end
- else
- return fsm:prev()
- end
-end
-
-return {
- name = "partition_disk",
- title = "Partition Disk",
- action = function(fsm)
- local choices = {}
-
- if App.state.sel_disk:has_been_touched() then
- return do_edit_partitions(fsm)
- end
-
- if App.state.sel_disk:get_part_count() == 0 then
- App.ui:inform(_(
- "No valid partitions were found on this disk. " ..
- "You will have to create at least one in which " ..
- "to install %s.",
- App.os.name
- ))
- return do_edit_partitions(fsm)
- end
-
- choices[_("Format and Partition Disk")] = function()
- return do_edit_partitions(fsm)
- end
-
- choices[_("Skip this Step")] = function()
- return fsm:next()
- end
-
- choices[_("Return to %s", fsm:prev().title)] = function()
- return fsm:prev()
- end
-
- return App.ui:select(_(
- "You may now format and partition this disk if you desire." ..
- "\n\n" ..
- "If this is a brand new disk, you should do this. If you " ..
- "would like to place multiple operating systems on this disk, " ..
- "you should create multiple partitions, one for each operating " ..
- "system." ..
- "\n\n" ..
- "If this disk already has operating systems on it that you wish " ..
- "to keep, you should NOT do this, and should skip this step." ..
- "\n\n" ..
- "Format and partition this disk?"),
- choices
- )()
- end
-}
+++ /dev/null
--- $Id: 270_install_bootblocks.lua,v 1.6 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-
-return {
- name = "install_bootblocks",
- title = "Install Bootblocks",
- action = function(fsm)
- local datasets_list = {}
- local dataset
- local dd
- local disk_ref = {} -- map from raw name to ref to DiskDescriptor
-
- for dd in App.state.storage:get_disks() do
- local raw_name = dd:get_raw_device_name()
-
- disk_ref[raw_name] = dd
-
- dataset = {
- disk = raw_name,
- boot0cfg = "Y",
- packet = "N"
- }
-
- if dd:get_capacity() > 8192 then
- dataset.packet = "Y"
- end
-
- table.insert(datasets_list, dataset)
- end
-
- local response = App.ui:present({
- id = "install_bootstrap",
- name = _("Install Bootblock(s)"),
- short_desc = _(
- "You may now wish to install bootblocks on one or more disks. " ..
- "If you already have a boot manager installed, you can skip " ..
- "this step (but you may have to configure your boot manager " ..
- "separately.) If you installed %s on a disk other " ..
- "than your first disk, you will need to put the bootblock " ..
- "on at least your first disk and the %s disk.",
- App.os.name, App.os.name),
- long_desc = _(
- "'Packet Mode' refers to using newer BIOS calls to boot " ..
- "from a partition of the disk. It is generally not " ..
- "required unless:\n\n" ..
- "- your BIOS does not support legacy mode; or\n" ..
- "- your %s primary partition resides on a " ..
- "cylinder of the disk beyond cylinder 1024; or\n" ..
- "- you just can't get it to boot without it.",
- App.os.name
- ),
- special = "bsdinstaller_install_bootstrap",
-
- fields = {
- {
- id = "disk",
- name = _("Disk Drive"),
- short_desc = _("The disk on which you wish to install a bootblock"),
- editable = "false"
- },
- {
- id = "boot0cfg",
- name = _("Install Bootblock?"),
- short_desc = _("Install a bootblock on this disk"),
- control = "checkbox"
- },
- {
- id = "packet",
- name = _("Packet mode?"),
- short_desc = _("Select this to use 'packet mode' to boot the disk"),
- control = "checkbox"
- }
- },
-
- actions = {
- {
- id = "ok",
- name = _("Accept and Install Bootblocks")
- },
- {
- id = "cancel",
- name = _("Skip this Step")
- }
- },
-
- datasets = datasets_list,
-
- multiple = "true",
- extensible = "false"
- })
-
- if response.action_id == "ok" then
- local cmds = CmdChain.new()
- local i
-
- for i, dataset in response.datasets do
- if dataset.boot0cfg == "Y" then
- dd = disk_ref[dataset.disk]
- dd:cmds_install_bootblock(cmds,
- (dataset.packet == "Y"))
- end
- end
-
- cmds:execute()
- end
-
- return fsm:next()
- end
-}
+++ /dev/null
--- $Id: 300_select_part.lua,v 1.17 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-require "storage_ui"
-
-return {
- name = "select_part",
- title = "Select Partition",
- action = function(fsm)
- App.state.sel_part = nil
-
- local pd = StorageUI.select_part({
- dd = App.state.sel_disk,
- short_desc = _(
- "Select the primary partition of %s (also " ..
- "known as a `slice' in the BSD tradition) on " ..
- "which to install %s.",
- App.state.sel_disk:get_name(),
- App.os.name),
- cancel_desc = _("Return to %s", fsm:prev().title)
- })
-
- if pd then
- if pd:is_mounted() then
- App.ui:inform(
- _("One or more subpartitions on the selected " ..
- "primary partition already in use (they are " ..
- "currently mounted in the filesystem.) " ..
- "You should either unmount them before " ..
- "proceeding, or select a different partition " ..
- "or disk on which to install %s.", App.os.name))
- return fsm:current()
- end
-
- if pd:get_activated_swap() > 0 then
- local choices = {}
-
- choices[_("Reboot")] = "reboot"
- choices[_("Return to %s", fsm:prev().title)] = fsm:prev()
-
- return App.ui:select(
- _("Some subpartitions on the selected primary " ..
- "partition are already activated as swap. " ..
- "Since there is no way to deactivate swap in " ..
- "%s once it is activated, in order " ..
- "to edit the subpartition layout of this " ..
- "primary partition, you must first reboot.",
- App.os.name), choices)
- end
-
- App.state.sel_part = pd
-
- if pd:get_capacity() < App.state.disk_min then
- App.ui:inform(_(
- "WARNING: you should have a primary " ..
- "partition at least %dM in size, or " ..
- "you may encounter problems trying to " ..
- "install %s.",
- App.state.disk_min, App.os.name)
- )
- end
-
- if App.state.sel_disk:has_been_touched() or
- App.ui:confirm(_(
- "WARNING! ALL data in primary partition #%d,\n\n%s\n\non the " ..
- "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you " ..
- "ABSOLUTELY SURE you wish to take this action? This is " ..
- "your LAST CHANCE to cancel!",
- pd:get_number(), pd:get_desc(),
- App.state.sel_disk:get_desc())) then
- local cmds = CmdChain.new()
-
- pd:cmds_format(cmds)
- if cmds:execute() then
- App.ui:inform(_(
- "Primary partition #%d was formatted.",
- pd:get_number())
- )
- return fsm:next()
- else
- App.ui:inform(_(
- "Primary partition #%d was " ..
- "not correctly formatted, and may " ..
- "now be in an inconsistent state. " ..
- "We recommend re-formatting it " ..
- "before proceeding.",
- pd:get_number())
- )
- return fsm:current()
- end
- else
- App.ui:inform(_(
- "Action cancelled - " ..
- "no primary partitions were formatted."))
- return fsm:prev()
- end
- else
- return fsm:prev()
- end
- end
-}
+++ /dev/null
--- $Id: 400_select_subparts.lua,v 1.24 2005/03/29 13:12:43 den Exp $
-
-local expert_mode = false
-
-local datasets_list = nil
-
-local fillout_missing_expert_values = function()
- local i, size
-
- for i in datasets_list do
- local dataset = datasets_list[i]
-
- if not dataset.softupdates and
- not dataset.fsize and not dataset.bsize then
- if dataset.mountpoint == "/" then
- dataset.softupdates = "N"
- else
- dataset.softupdates = "Y"
- end
-
- size = StorageDescriptor.parse_capstring(dataset.capstring, -1)
- if size and size < (1024 * 1024 * 1024) then
- dataset.fsize = "1024"
- dataset.bsize = "8192"
- else
- dataset.fsize = "2048"
- dataset.bsize = "16384"
- end
- end
- end
-end
-
-local warn_subpartition_selections = function(pd)
- local omit = ""
- local consequences = ""
-
- if not pd:get_subpart_by_mountpoint("/var") then
- omit = omit .. "/var "
- consequences = consequences ..
- _("%s will be a plain dir in %s\n", "/var", "/")
- end
-
- if not pd:get_subpart_by_mountpoint("/usr") then
- omit = omit .. "/usr "
- consequences = consequences ..
- _("%s will be a plain dir in %s\n", "/usr", "/")
- end
-
- if not pd:get_subpart_by_mountpoint("/tmp") then
- omit = omit .. "/tmp "
- consequences = consequences ..
- _("%s will be symlinked to %s\n", "/tmp", "/var/tmp")
- end
-
- if not pd:get_subpart_by_mountpoint("/home") then
- omit = omit .. "/home "
- consequences = consequences ..
- _("%s will be symlinked to %s\n", "/home", "/usr/home")
- end
-
- if string.len(omit) > 0 then
- local choices = {}
-
- choices[_("Omit Subpartition(s)")] = true
- choices[_("Return to Create Subpartitions")] = false
-
- return App.ui:select(_(
- "You have elected to not have the following " ..
- "subpartition(s):\n\n%s\n\n" ..
- "The ramifications of these subpartition(s) being " ..
- "missing will be:\n\n%s\n" ..
- "Is this really what you want to do?",
- omit, consequences), choices)
- else
- return true
- end
-end
-
-local validate_subpart_descriptors = function(pd)
- local spd, k, v
- local part_size = pd:get_size()
- local used_size = 0
- local min_size = {}
-
- -- XXX this should come from a config file.
- for k, v in {
- ["/"] = "70M",
- ["/var"] = "8M",
- ["/usr"] = "174M"
- } do
- min_size[k] = StorageDescriptor.parse_capstring(v, 0) or 0
- end
-
- --
- -- If the user didn't select a /usr partition, / is going to
- -- have to hold all that stuff - so make sure it's big enough.
- --
- if not pd:get_subpart_by_mountpoint("/usr") then
- min_size["/"] = min_size["/"] + min_size["/usr"]
- end
-
- for spd in pd:get_subparts() do
- local spd_size = spd:get_size()
- local mtpt = spd:get_mountpoint()
- local min_mt_size = min_size[mtpt]
-
- used_size = used_size + spd_size
-
- if min_mt_size and spd_size < min_mt_size then
- if not App.ui:confirm(_(
- "WARNING: the %s subpartition should " ..
- "be at least %s in size or you will " ..
- "risk running out of space during " ..
- "the installation.\n\n" ..
- "Proceed anyway?",
- mtpt,
- StorageDescriptor.format_capstring(min_mt_size))) then
- return false
- end
- end
- end
-
- if used_size > part_size then
- if not App.ui:confirm(_(
- "WARNING: The total number of sectors needed " ..
- "for the requested subpartitions (%d) exceeds the " ..
- "number of sectors available in the partition (%d) " ..
- "by %d sectors (%s.)\n\n" ..
- "This is an invalid configuration; we " ..
- "recommend shrinking the size of one or " ..
- "more subpartitions before proceeding.\n\n" ..
- "Proceed anyway?",
- used_size, part_size, used_size - part_size,
- StorageDescriptor.format_capstring(used_size - part_size))) then
- return false
- end
- end
-
- if used_size < part_size - App.state.max_waste then
- if not App.ui:confirm(_(
- "Note: the total capacity required " ..
- "for the requested subpartitions (%s) does not make " ..
- "full use of the capacity available in the " ..
- "partition (%s.) %d sectors (%s) of space will go " ..
- "unused.\n\n" ..
- "You may wish to expand one or more subpartitions " ..
- "before proceeding.\n\n" ..
- "Proceed anyway?",
- StorageDescriptor.format_capstring(used_size),
- StorageDescriptor.format_capstring(part_size),
- part_size - used_size,
- StorageDescriptor.format_capstring(part_size - used_size))) then
- return false
- end
- end
-
- if App.option.enable_crashdumps then
- local num_swap_subparts = 0
- local num_dumponable = 0
-
- for spd in pd:get_subparts() do
- if spd:is_swap() then
- num_swap_subparts = num_swap_subparts + 1
- if spd:get_capacity() >= App.state.store:get_ram() then
- num_dumponable = num_dumponable + 1
- end
- end
- end
-
- if num_swap_subparts > 0 and num_dumponable == 0 then
- if not App.ui:confirm(_(
- "Note: none of the swap subpartitions that " ..
- "you have selected are large enough to hold " ..
- "the contents of memory, and thus cannot be " ..
- "used to hold a crash dump (an image of the " ..
- "computers' memory at the time of failure.) " ..
- "Because this complicates troubleshooting, " ..
- "we recommend that you increase the size of " ..
- "one of your swap subpartitions.\n\n" ..
- "Proceed anyway?",
- mtpt, min_cap)) then
- return false
- end
- end
- end
-
- return warn_subpartition_selections(pd)
-end
-
---
--- Take a list of tables representing the user's choices and
--- create a matching set of subpartition descriptors under
--- the given partition description from them. In the process,
--- the desired subpartitions are checked for validity.
---
-local create_subpart_descriptors = function(pd, list)
- local i, letter, dataset
- local size, offset, fstype
- local total_size = 0
- local wildcard_size = false
-
- pd:clear_subparts()
-
- offset = 0
- for i, dataset in list do
- if dataset.capstring == "*" then
- if wildcard_size then
- App.ui:inform(_(
- "Only one subpartition may have " ..
- "a capacity of '*'."
- ))
- return false
- end
- wildcard_size = true
- end
- size = StorageDescriptor.parse_capstring(dataset.capstring, 0)
- if not size then
- App.ui:inform(_(
- "Capacity must either end in 'M' " ..
- "for megabytes, 'G' for gigabytes, " ..
- "or be '*' to indicate 'use all " ..
- "remaining space.'"
- ))
- return false
- end
- total_size = total_size + size
- end
-
- offset = 0
- for i, letter in ipairs({"a", "b", "d", "e", "f", "g", "h", "i",
- "j", "k", "l", "m", "n", "o", "p" }) do
- if i > table.getn(list) then break end
- dataset = list[i]
-
- size = StorageDescriptor.parse_capstring(dataset.capstring,
- pd:get_size() - total_size)
-
- if dataset.mountpoint == "swap" then
- fstype = "swap"
- else
- fstype = "4.2BSD"
- end
-
- pd:add_subpart(SubpartitionDescriptor.new{
- parent = pd,
- letter = letter,
- size = size,
- offset = offset,
- fstype = fstype,
- fsize = tonumber(dataset.fsize),
- bsize = tonumber(dataset.bsize),
- mountpoint = dataset.mountpoint
- })
-
- offset = offset + size
- end
-
- return validate_subpart_descriptors(pd)
-end
-
-return {
- name = "select_subparts",
- title = "Select Subpartitions",
- action = function(fsm)
- local part_no, pd
- local part_actions = {}
- local i, letter
-
- if not datasets_list then
- datasets_list = App.load_conf("mountpoints")(
- App.state.sel_part:get_capacity(),
- App.state.storage:get_ram()
- )
- end
-
- local fields_list = {
- {
- id = "mountpoint",
- name = _("Mountpoint")
- },
- {
- id = "capstring",
- name = _("Capacity")
- }
- }
-
- local actions_list = {
- {
- id = "ok",
- name = _("Accept and Create"),
- effect = function()
- return fsm:next()
- end
- },
- {
- id = "cancel",
- name = _("Return to %s", fsm:prev().title),
- effect = function()
- return fsm:prev()
- end
- }
- }
-
- if expert_mode then
- table.insert(fields_list,
- {
- id = "softupdates",
- name = _("Softupdates?"),
- control = "checkbox"
- }
- )
- table.insert(fields_list,
- {
- id = "fsize",
- name = _("Frag Size")
- }
- )
- table.insert(fields_list,
- {
- id = "bsize",
- name = _("Block Size")
- }
- )
-
- table.insert(actions_list,
- {
- id = "switch",
- name = _("Switch to Normal Mode"),
- effect = function()
- expert_mode = not expert_mode
- return fsm:current()
- end
- }
- )
- else
- table.insert(actions_list,
- {
- id = "switch",
- name = _("Switch to Expert Mode"),
- effect = function()
- expert_mode = not expert_mode
- return fsm:current()
- end
- }
- )
- end
-
- local response = App.ui:present({
- id = "select_subpartitions",
- name = _("Select Subpartitions"),
- short_desc = _("Set up the subpartitions (also known " ..
- "as just `partitions' in BSD tradition) you want to " ..
- "have on this primary partition.\n\n" ..
- "For Capacity, use 'M' to indicate megabytes, 'G' to " ..
- "indicate gigabytes, or a single '*' to indicate " ..
- "'use the remaining space on the primary partition'."),
- long_desc = _("Subpartitions further divide a primary partition for " ..
- "use with %s. Some reasons you may want " ..
- "a set of subpartitions are:\n\n" ..
- "- you want to restrict how much data can be written " ..
- "to certain parts of the primary partition, to quell " ..
- "denial-of-service attacks; and\n" ..
- "- you want to speed up access to data on the disk.",
- App.os.name),
- special = "bsdinstaller_create_subpartitions",
- minimum_width = "64",
-
- actions = actions_list,
- fields = fields_list,
- datasets = datasets_list,
-
- multiple = "true",
- extensible = "true"
- })
-
- -- remember these subpartition selections in case we come back here.
- datasets_list = response.datasets
- fillout_missing_expert_values()
-
- if response.action_id == "ok" then
- if create_subpart_descriptors(App.state.sel_part, datasets_list) then
- local cmds = CmdChain.new()
-
- App.state.sel_part:cmds_disklabel(cmds)
- cmds:execute()
- else
- return fsm:current()
- end
- end
-
- return response.result
- end
-}
+++ /dev/null
--- $Id: 450_select_packages.lua,v 1.4 2005/02/24 23:08:04 cpressey Exp $
-
-require "package"
-require "storage_ui"
-
-return {
- name = "select_packages",
- title = "Select Packages",
- action = function(fsm)
- local i, j, pkg, regexp
-
- if not App.state.sel_pkgs then
- local pkg_list = Package.list_all("")
- local def_pkgs = App.load_conf("def_pkgs") or {}
-
- App.state.sel_pkgs = {}
- for i, pkg in pkg_list do
- App.state.sel_pkgs[pkg] = false -- but present...
- for j, regexp in def_pkgs do
- if string.find(pkg, regexp) then
- App.state.sel_pkgs[pkg] = true
- end
- end
- end
- end
-
- local ok, sel_pkgs = StorageUI.select_packages{
- name = _("Select Packages"),
- short_desc = _("Select the packages you wish to install from " ..
- "the LiveCD onto the HDD."),
- checkbox_name = _("Install?"),
- ok_name = _("Accept these Packages"),
- cancel_name = _("Return to %s", fsm:prev().title),
-
- sel_pkgs = App.state.sel_pkgs
- }
-
- if ok then
- App.state.sel_pkgs = sel_pkgs
- return fsm:next()
- else
- return fsm:prev()
- end
- end
-}
+++ /dev/null
--- $Id: 500_install_os.lua,v 1.39 2005/04/05 07:37:20 cpressey Exp $
-
-require "gettext"
-require "target_system"
-
-return {
- name = "install_os",
- title = "Install OS",
- action = function(fsm)
- local spd, cmds
-
- --
- -- Final confirmation.
- --
- if App.ui:present({
- id = "ready_to_install",
- name = _("Ready to Install"),
- short_desc = _(
- "Everything is now ready to install the actual files which " ..
- "comprise the %s operating system " ..
- "on the selected partition of the selected disk.\n\n" ..
- "Note that this process will take quite a while to finish. " ..
- "You may wish to take a break now and come back to the " ..
- "computer in a short while.", App.os.name),
- actions = {
- {
- id = "ok",
- name = _("Begin Installing Files")
- },
- {
- id = "cancel",
- name = _("Return to %s", fsm:prev().title)
- }
- }
- }).action_id ~= "ok" then
- return fsm:prev()
- end
-
- --
- -- If there is a target system mounted, unmount it before starting.
- --
- if App.state.target ~= nil and App.state.target:is_mounted() then
- if not App.state.target:unmount() then
- App.ui:inform(
- _("Warning: already-mounted target system could " ..
- "not be correctly unmounted first."))
- return fsm:current()
- end
- end
-
- --
- -- Create a command chain.
- --
- cmds = CmdChain.new()
-
- --
- -- Activate swap, if there is none activated so far.
- --
- if App.state.storage:get_activated_swap() == 0 then
- for spd in App.state.sel_part:get_subparts() do
- if spd:get_fstype() == "swap" then
- cmds:add{
- cmdline = "${root}${SWAPON} ${root}dev/${dev}",
- replacements = {
- dev = spd:get_device_name()
- }
- }
- end
- end
- end
-
- --
- -- Mount the target system. This will create the
- -- mountpoint directories the user asked for and
- -- will mount their subpartitions on them.
- --
- App.state.target = TargetSystem.new(App.state.sel_part, "mnt")
- if not App.state.target:create() then
- App.ui:inform(
- _("Could not create the skeletal target system.")
- )
- return fsm:current()
- end
- if not App.state.target:mount() then
- App.ui:inform(
- _("Could not mount the skeletal target system.")
- )
- return fsm:current()
- end
-
- --
- -- Create the commands which will install the chosen directories
- -- onto the target system.
- --
- App.state.target:cmds_install_srcs(cmds, App.load_conf("sources"))
-
- --
- -- If we were to copy /usr/local and /usr/X11R6 onto the HDD,
- -- *all* packages installed on the LiveCD would be copied to
- -- the HDD. This may not be what the user wants. So instead,
- -- create an appropriate filesystem hierarchy under /usr/local
- -- and /usr/X11R6 and populate them with only mandatory packages.
- -- And first, remove the copied-over package database, as it is
- -- inaccurate.
- --
- cmds:add(
- "${root}${RM} -rf ${root}mnt/var/db/pkg",
- "${root}${MKDIR} -p ${root}mnt/var/db/pkg",
- "${root}${CHMOD} 755 ${root}mnt/var/db/pkg",
- "${root}${MKDIR} -p ${root}mnt/usr/local",
- "${root}${MTREE} -deU -f ${root}etc/mtree/BSD.local.dist -p ${root}mnt/usr/local",
- "${root}${MKDIR} -p ${root}mnt/usr/X11R6",
- "${root}${MTREE} -deU -f ${root}etc/mtree/BSD.x11-4.dist -p ${root}mnt/usr/X11R6"
- )
-
- --
- -- Create symlinks.
- --
-
- --
- -- If the user has both /var and /tmp subparitions,
- -- symlink /var/tmp to /tmp.
- --
- if App.state.sel_part:get_subpart_by_mountpoint("/tmp") and
- App.state.sel_part:get_subpart_by_mountpoint("/var") then
- cmds:add(
- "${root}${CHMOD} 1777 ${root}mnt/tmp",
- "${root}${RM} -rf ${root}mnt/var/tmp",
- "${root}${LN} -s /tmp ${root}mnt/var/tmp"
- )
- end
-
- --
- -- If the user has /var, but no /tmp,
- -- symlink /tmp to /var/tmp.
- --
- if not App.state.sel_part:get_subpart_by_mountpoint("/tmp") and
- App.state.sel_part:get_subpart_by_mountpoint("/var") then
- cmds:add(
- "${root}${RM} -rf ${root}mnt/tmp",
- "${root}${LN} -s /var/tmp ${root}mnt/tmp"
- )
- end
-
- --
- -- If the user has /usr, but no /home,
- -- symlink /home to /usr/home.
- --
- if not App.state.sel_part:get_subpart_by_mountpoint("/home") and
- App.state.sel_part:get_subpart_by_mountpoint("/usr") then
- cmds:add(
- "${root}${RM} -rf ${root}mnt/home",
- "${root}${MKDIR} ${root}mnt/usr/home",
- "${root}${LN} -s /usr/home ${root}mnt/home"
- )
- end
-
- --
- -- Clean up. In case some file didn't make it, use rm -f
- --
- if App.os == "DragonFly" then
- cmds:add("${root}${RM} -f ${root}mnt/boot/loader.conf")
- end
- cmds:set_replacements{
- logfile = App.log_filename,
- part = App.state.sel_part:get_device_name()
- }
- cmds:add("${root}${RM} -f ${root}mnt/tmp/${logfile}")
-
- --
- -- Create missing directories.
- --
- cmds:add(
- "${root}${MKDIR} ${root}mnt/proc",
- "${root}${MKDIR} ${root}mnt/mnt"
- )
-
- --
- -- Write the fstab.
- --
- App.state.sel_part:cmds_write_fstab(cmds, "${root}mnt/etc/fstab")
-
- --
- -- If it was enabled and selected, write the crash device
- -- in the user's new rc.conf file on the HDD.
- --
- if App.state.crash_device ~= nil then
- local cv = ConfigVars.new()
-
- cv:set("dumpdev", "/dev/" .. App.state.crash_device)
- cv:set("dumpdir", "/var/crash")
- cv:write(App.expander:expand("${root}mnt/etc/rc.conf"), "sh")
- end
-
- --
- -- Install requested packages.
- --
- if App.state.sel_pkgs ~= nil then
- local pkg_name, selected
- local pkg_seen = {}
- local n, i = 0, 0
- local pr = App.ui:new_progress_bar{
- title = _("Calculating package dependencies...")
- }
-
- for pkg_name, selected in App.state.sel_pkgs do
- if selected then
- n = n + 1
- end
- end
-
- pr:start()
- for pkg_name, selected in App.state.sel_pkgs do
- if selected then
- Package.cmds_copy(
- "mnt/", cmds, pkg_name, pkg_seen
- )
- i = i + 1
- pr:set_amount((i * 100) / n)
- pr:update()
- end
- end
- pr:stop()
- end
-
- --
- -- Backup the disklabel and the log.
- --
- cmds:add(
- "${root}${DISKLABEL} ${part} >${root}mnt/etc/disklabel.${part}",
- "${root}${CP} ${tmp}${logfile} ${root}mnt/var/log/${logfile}",
- "${root}${CHMOD} 600 ${root}mnt/var/log/${logfile}"
- )
-
- --
- -- Do it!
- --
- if cmds:execute() then
- --
- -- If the install went successfully,
- -- make sure once and for all that the disklabel is bootable.
- --
- cmds = CmdChain.new()
- App.state.sel_part:cmds_install_bootstrap(cmds)
- if not cmds:execute() then
- App.ui:inform(
- _("Failed to make sure that the partition is bootable.")
- )
- end
- return fsm:next()
- else
- App.ui:inform(
- _("%s was not fully installed.", App.os.name)
- )
- return fsm:current()
- end
- end
-}
+++ /dev/null
--- $Id: 700_install_bootblocks.lua,v 1.6 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-
-return {
- name = "install_bootblocks",
- title = "Install Bootblocks",
- action = function(fsm)
- local datasets_list = {}
- local dataset
- local dd
- local disk_ref = {} -- map from raw name to ref to DiskDescriptor
-
- for dd in App.state.storage:get_disks() do
- local raw_name = dd:get_raw_device_name()
-
- disk_ref[raw_name] = dd
-
- dataset = {
- disk = raw_name,
- boot0cfg = "Y",
- packet = "N"
- }
-
- if dd:get_capacity() > 8192 then
- dataset.packet = "Y"
- end
-
- table.insert(datasets_list, dataset)
- end
-
- local response = App.ui:present({
- id = "install_bootstrap",
- name = _("Install Bootblock(s)"),
- short_desc = _(
- "You may now wish to install bootblocks on one or more disks. " ..
- "If you already have a boot manager installed, you can skip " ..
- "this step (but you may have to configure your boot manager " ..
- "separately.) If you installed %s on a disk other " ..
- "than your first disk, you will need to put the bootblock " ..
- "on at least your first disk and the %s disk.",
- App.os.name, App.os.name),
- long_desc = _(
- "'Packet Mode' refers to using newer BIOS calls to boot " ..
- "from a partition of the disk. It is generally not " ..
- "required unless:\n\n" ..
- "- your BIOS does not support legacy mode; or\n" ..
- "- your %s primary partition resides on a " ..
- "cylinder of the disk beyond cylinder 1024; or\n" ..
- "- you just can't get it to boot without it.",
- App.os.name
- ),
- special = "bsdinstaller_install_bootstrap",
-
- fields = {
- {
- id = "disk",
- name = _("Disk Drive"),
- short_desc = _("The disk on which you wish to install a bootblock"),
- editable = "false"
- },
- {
- id = "boot0cfg",
- name = _("Install Bootblock?"),
- short_desc = _("Install a bootblock on this disk"),
- control = "checkbox"
- },
- {
- id = "packet",
- name = _("Packet mode?"),
- short_desc = _("Select this to use 'packet mode' to boot the disk"),
- control = "checkbox"
- }
- },
-
- actions = {
- {
- id = "ok",
- name = _("Accept and Install Bootblocks")
- },
- {
- id = "cancel",
- name = _("Skip this Step")
- }
- },
-
- datasets = datasets_list,
-
- multiple = "true",
- extensible = "false"
- })
-
- if response.action_id == "ok" then
- local cmds = CmdChain.new()
- local i
-
- for i, dataset in response.datasets do
- if dataset.boot0cfg == "Y" then
- dd = disk_ref[dataset.disk]
- dd:cmds_install_bootblock(cmds,
- (dataset.packet == "Y"))
- end
- end
-
- cmds:execute()
- end
-
- return fsm:next()
- end
-}
+++ /dev/null
--- $Id: 800_finished.lua,v 1.8 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-
-return {
- name = "finished",
- title = "Finished",
- action = function(fsm)
- return App.ui:present({
- id = "finished_install",
- name = _("%s is now installed", App.os.name),
- short_desc = _("Congratulations, %s is now installed " ..
- "on your hard drive! You may now do one " ..
- "of three things: you can perform some " ..
- "initial configuration of this system, you " ..
- "can reboot to test out your new " ..
- "installation, or you can go back to the " ..
- "main menu and select other actions to " ..
- "perform.",
- App.os.name),
- actions = {
- {
- id = "configure",
- name = _("Configure"),
- short_desc = _("Configure the system that was just installed"),
- effect = function()
- App.descend("../configure/menu")
- return nil
- end
- },
- {
- id = "reboot",
- name = _("Reboot"),
- short_desc = _("Reboot this computer"),
- effect = function()
- return fsm:next()
- end
- },
- {
- id = "cancel",
- name = _("Return to Main Menu"),
- short_desc = _("Return to Main Menu"),
- effect = function()
- return nil
- end
- }
- }
- }).result
- end
-}
+++ /dev/null
--- $Id: 900_reboot.lua,v 1.7 2005/02/24 23:08:04 cpressey Exp $
-
-require "gettext"
-
-return {
- name = "reboot",
- title = "Reboot",
- action = function()
- local response = App.ui:present({
- id = "reboot",
- name = _("Reboot"),
- short_desc = _("This machine is about to be shut down. " ..
- "After the machine has reached its shutdown state, " ..
- "you may remove the CD from the CD-ROM drive tray " ..
- "and press Enter to reboot from the HDD."),
- role = "confirm",
- actions = {
- {
- id = "ok",
- name = _("Reboot"),
- },
- {
- id = "cancel",
- name = _("Return to Main Menu"),
- }
- }
- })
-
- App.state.do_reboot = (response.action_id == "ok")
-
- return nil
- end
-}
+++ /dev/null
--- demo/install/main.lua
--- $Id: main.lua,v 1.4 2005/02/24 23:08:04 cpressey Exp $
--- Main segment of the demonstration fake install program.
-
-require "fsm"
-
--- these are really more like settings...
--- and as such should go in a config file...
-App.state.disk_min = 300 -- minimum space (in MB) req'd for install
-App.state.max_waste = 8192 -- maximum # sectors to allow to go to waste
- -- when defining partitions/subpartitions
-
-FSM.auto("welcome")
+++ /dev/null
--- lib/bitwise.lua
--- $Id: Bitwise.lua,v 1.1 2005/02/22 02:54:32 cpressey Exp $
--- Package for (pure-Lua portable but extremely slow) bitwise arithmetic.
-
--- BEGIN lib/bitwise.lua --
-
---[[---------]]--
---[[ Bitwise ]]--
---[[---------]]--
-
-local odd = function(x)
- return x ~= math.floor(x / 2) * 2
-end
-
-Bitwise = {}
-
-Bitwise.bw_and = function(a, b)
- local c, pow = 0, 1
- while a > 0 or b > 0 do
- if odd(a) and odd(b) then
- c = c + pow
- end
- a = math.floor(a / 2)
- b = math.floor(b / 2)
- pow = pow * 2
- end
- return c
-end
-
-Bitwise.bw_or = function(a, b)
- local c, pow = 0, 1
- while a > 0 or b > 0 do
- if odd(a) or odd(b) then
- c = c + pow
- end
- a = math.floor(a / 2)
- b = math.floor(b / 2)
- pow = pow * 2
- end
- return c
-end
-
--- END of lib/bitwise.lua --
+++ /dev/null
--- lib/storage.lua
--- $Id: Capacity.lua,v 1.76 2005/03/29 21:04:19 cpressey Exp $
--- Storage Descriptors (a la libinstaller) in Lua.
-
--- BEGIN lib/storage.lua --
-
-local App = require("app")
-local FileName = require("filename")
-require "cmdchain"
-require "bitwise"
-require "mountpoint"
-
---
--- Note: these methods should try to use consistent terminology:
---
--- 'capacity' of an object refers to its capacity in megabytes.
--- 'size' of an object refers to its size in blocks or sectors
--- (which are assumed to be 512 bytes each.)
--- 'capstring' refers to a string which includes a unit suffix:
--- 'M' for megabytes
--- 'G' for gigabytes
--- '*' to indicate 'use the remaining space on the device'
---
-
---[[-------------------]]--
---[[ StorageDescriptor ]]--
---[[-------------------]]--
-
--- This class returns an object which can represent
--- the system's data storage capabilities.
-
-StorageDescriptor = {}
-StorageDescriptor.new = function()
- local disk = {} -- disks in this storage descriptor
- local ram = 0 -- in megabytes
- local sd = {} -- instance variable
-
- -- Internal function.
- local next_power_of_two = function(n)
- local i = 1
- n = math.ceil(n)
-
- while i < n and i >= 1 do
- i = i * 2
- end
-
- if i > n then
- return i
- else
- return n
- end
- end
-
- -- Now set up this object's interface functions
-
- -- Look through `dmesg', `atacontrol list', etc, and
- -- populate disks and ram with values
- -- that are as accurate and readable as possible.
- -- XXX not yet fully implemented.
- sd.survey = function(sd)
- local pty, line
- local disk_name, dd
- local cmd
- local found, len, cap
-
- cmd = App.expand("${root}${SYSCTL} -n hw.physmem")
- pty = Pty.open(cmd)
- line = pty:readline()
- pty:close()
-
- App.log("`" .. cmd .. "` returned: " .. line)
-
- ram = next_power_of_two(tonumber(line) / (1024 * 1024))
-
- cmd = App.expand("${root}${SYSCTL} -n kern.disks")
- pty = Pty.open(cmd)
- line = pty:readline()
- pty:close()
-
- App.log("`" .. cmd .. "` returned: " .. line)
-
- for disk_name in string.gfind(line, "%s*(%w+)") do
- if not string.find(disk_name, "^md") then
- disk[disk_name] = DiskDescriptor.new(sd, disk_name)
- end
- end
-
- for line in io.lines("/var/run/dmesg.boot") do
- for disk_name, dd in disk do
- found, len, cap =
- string.find(line, "^" .. disk_name .. ":%s*(.*)$")
- if found then
- dd:set_desc(disk_name .. ": " .. cap)
- end
- end
- end
-
- cmd = App.expand("${root}${ATACONTROL} list")
- pty = Pty.open(cmd)
- line = pty:readline()
- while line do
- for disk_name, dd in disk do
- found, len, cap =
- string.find(line, "^%s*Master:%s*" ..
- disk_name .. "%s*(%<.*%>)$")
- if not found then
- found, len, cap =
- string.find(line, "^%s*Slave:%s*" ..
- disk_name .. "%s*(%<.*%>)$")
- end
- if found then
- dd:set_desc(disk_name .. ": " .. cap)
- end
- end
- line = pty:readline()
- end
- pty:close()
- end
-
- -- Refresh our view of the storage connected to the
- -- system, but remember what disk and/or partition
- -- was selected as well.
- sd.resurvey = function(sd, sel_disk, sel_part)
- local sel_disk_name, sel_part_no
-
- if sel_disk then
- sel_disk_name = sel_disk:get_name()
- end
-
- if sel_part then
- sel_part_no = sel_part:get_number()
- end
-
- sd:survey()
-
- if sel_disk then
- sel_disk = sd:get_disk_by_name(sel_disk_name)
- if not sel_disk then
- -- XXX warn that sel disk was lost!
- end
- end
-
- if sel_disk and sel_part then
- sel_part = sel_disk:find_part_by_number(sel_part_no)
- if not sel_part then
- -- XXX warn that sel part was lost!
- end
- end
-
- return sel_disk, sel_part
- end
-
- -- Return an iterator which yields the next next
- -- DiskDescriptor object in this StorageDescriptor
- -- each time it is called (typically in a for loop.)
- sd.get_disks = function(sd)
- local disk_name, dd
- local list = {}
- local i, n = 0, 0
-
- for disk_name, dd in disk do
- table.insert(list, dd)
- n = n + 1
- end
-
- table.sort(list, function(a, b)
- return a:get_name() < b:get_name()
- end)
-
- return function()
- if i <= n then
- i = i + 1
- return list[i]
- end
- end
- end
-
- -- Given the name of a disk, return that disk descriptor,
- -- or nil if no disk by that name was found.
- sd.get_disk_by_name = function(sd, name)
- local dd
-
- for dd in sd:get_disks() do
- if dd:get_name() == name then
- return dd
- end
- end
-
- return nil
- end
-
- sd.get_disk_count = function(sd)
- local disk_name, dd
- local n = 0
-
- for disk_name, dd in disk do
- n = n + 1
- end
-
- return n
- end
-
- sd.get_ram = function(sd) -- in megabytes
- return ram
- end
-
- sd.get_activated_swap = function(sd) -- in megabytes
- local pty, line
- local swap = 0
- local found, len, devname, amount
-
- pty = Pty.open(App.expand("${root}${SWAPINFO} -k"))
- line = pty:readline()
- while line do
- if not string.find(line, "^Device") then
- found, len, devname, amount =
- string.find(line, "^([^%s]+)%s+(%d+)")
- swap = swap + tonumber(amount)
- end
- line = pty:readline()
- end
- pty:close()
-
- return math.floor(swap / 1024)
- end
-
- sd.dump = function(sd)
- local disk_name, dd
-
- print("*** DUMP of StorageDescriptor ***")
- for disk_name, dd in disk do
- dd:dump()
- end
- end
-
- return sd
-end
-
---
--- The following global static utility functions in the
--- StorageDescriptor class are really human interface functions;
--- they might be better placed elsewhere.
---
-
---
--- Take a capstring and return a number indicating size in blocks.
--- If the capstring is "*", the supplied remainder is returned.
--- If the capstring could not be parsed, returns nil.
---
-StorageDescriptor.parse_capstring = function(str, remainder)
- if str == "*" then
- return remainder
- else
- local suffix = string.sub(str, -1, -1)
- local body = string.sub(str, 1, string.len(str) - 1)
-
- if suffix == "G" or suffix == "g" then
- return math.floor(tonumber(body) * 1024 * 1024 * 2)
- elseif suffix == "M" or suffix == "m" then
- return math.floor(tonumber(body) * 1024 * 2)
- else
- -- bad suffix
- return nil
- end
- end
-end
-
---
--- Takes a number specifying a size in blocks and
--- convert it to a capstring.
---
-StorageDescriptor.format_capstring = function(blocks)
- if blocks >= 1024 * 1024 * 2 then
- return tostring(math.floor(blocks / (1024 * 1024 * 2) * 100) / 100) .. "G"
- else
- return tostring(math.floor(blocks / (1024 * 2) * 100) / 100) .. "M"
- end
-end
-
-
---[[----------------]]--
---[[ DiskDescriptor ]]--
---[[----------------]]--
-
-DiskDescriptor = {}
-DiskDescriptor.new = function(parent, name)
- local dd = {} -- instance variable
- local part = {} -- private: partitions on this disk
- local desc = name -- private: description of disk
- local cyl, head, sec -- private: geometry of disk
- local touched = false -- private: whether we formatted it
-
- -- Set up this object instance's interface functions first:
-
- dd.get_parent = function(dd)
- return parent
- end
-
- dd.get_name = function(dd)
- return name
- end
-
- dd.set_desc = function(dd, new_desc)
- --
- -- Calculate a score for how well this string describes
- -- a disk. Reject obviously bogus descriptions (usually
- -- erroneously harvested from error messages in dmesg.)
- --
- local calculate_score = function(s)
- local score = 0
-
- -- In the absence of any good discriminator,
- -- the longest disk description wins.
- score = string.len(s)
-
- -- Look for clues
- if string.find(s, "%d+MB") then
- score = score + 10
- end
- if string.find(s, "%<.*%>") then
- score = score + 10
- end
- if string.find(s, "%[%d+%/%d+%/%d+%]") then
- score = score + 10
- end
-
- -- Look for error messages
- if string.find(s, "resetting") then
- score = 0
- end
-
- return score
- end
-
- if calculate_score(new_desc) > calculate_score(desc) then
- desc = new_desc
- end
- end
-
- dd.get_desc = function(dd)
- return desc
- end
-
- dd.get_geometry = function(dd)
- return cyl, head, sec
- end
-
- dd.get_device_name = function(dd)
- return name
- end
-
- dd.get_raw_device_name = function(dd)
- -- XXX depends on operating system
- return name
- end
-
- -- Return an iterator which yields the next next
- -- PartitionDescriptor object in this DiskDescriptor
- -- each time it is called (typically in a for loop.)
- dd.get_parts = function(dd)
- local i, n = 0, table.getn(part)
-
- return function()
- if i <= n then
- i = i + 1
- return part[i]
- end
- end
- end
-
- -- Given the number of a partition, return that
- -- partition descriptor, or nil if not found.
- dd.get_part_by_number = function(dd, number)
- local pd
-
- for pd in dd:get_parts() do
- if pd:get_number() == number then
- return pd
- end
- end
-
- return nil
- end
-
- dd.get_part_count = function(dd)
- return table.getn(part)
- end
-
- -- return the disk's capacity in megabytes.
- -- this is actually the sum of the capacities of the
- -- partitions on this disk.
- dd.get_capacity = function(dd)
- local pd
- local cap = 0
-
- for pd in dd:get_parts() do
- cap = cap + pd:get_capacity()
- end
-
- return cap
- end
-
- -- return the disk's raw size in sectors.
- dd.get_raw_size = function(dd)
- pty = Pty.open(App.expand(
- "${root}${FDISK} -t -I " ..
- dd:get_raw_device_name()))
- line = pty:readline()
- while line do
- local found, len, start, size =
- string.find(line, "start%s*(%d+)%s*,%s*size%s*(%d+)")
- if found then
- pty:close()
- return tonumber(start) + tonumber(size)
- end
- line = pty:readline()
- end
- pty:close()
-
- return nil
- end
-
- dd.touch = function(dd)
- touched = true
- end
-
- dd.has_been_touched = function(dd)
- return touched
- end
-
- --
- -- Determine whether any subpartition from any partition of this
- -- disk is mounted somewhere in the filesystem.
- --
- dd.is_mounted = function(dd)
- local fs_descs = MountPoints.enumerate()
- local i, fs_desc, dev_name
-
- dev_name = dd:get_device_name()
- for i, fs_desc in fs_descs do
- if string.find(fs_desc.device, dev_name, 1, true) then
- return true
- end
- end
-
- return false
- end
-
- --
- -- Methods to manipulate the contents of this DiskDescriptor.
- --
-
- dd.clear_parts = function(dd)
- part = {}
- end
-
- dd.add_part = function(dd, pd)
- part[pd:get_number()] = pd
- -- pd:set_parent(dd)
- end
-
- --
- -- Methods to add appropriate commands to CmdChains.
- --
-
- -- Commands to ensure this device exists.
- dd.cmds_ensure_dev = function(dd, cmds)
- cmds:add({
- cmdline = "cd ${root}dev && ${root}${TEST_DEV} ${dev} || " ..
- "${root}${SH} MAKEDEV ${dev}",
- replacements = {
- dev = FileName.basename(dd:get_device_name())
- }
- })
- end
-
- -- Commands to format this disk.
- dd.cmds_format = function(dd, cmds)
- dd:cmds_ensure_dev(cmds)
-
- --
- -- Currently you need to pass 'yes' to OpenBSD's fdisk to
- -- be able to do these. (This is a shot in the dark:)
- --
- if App.os.name == "OpenBSD" then
- cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " ..
- "${root}${FDISK} -I " ..
- dd:get_raw_device_name())
- cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " ..
- "${root}${FDISK} -B " ..
- dd:get_raw_device_name())
- else
- cmds:add("${root}${FDISK} -I " ..
- dd:get_raw_device_name())
- cmds:add("${root}${YES} | ${root}${FDISK} -B " ..
- dd:get_raw_device_name())
- end
- end
-
- -- Commands to partition this disk.
- dd.cmds_partition = function(dd, cmds)
- local i, pd
- local active_part_no
- local cyl, head, sec = dd:get_geometry()
-
- dd:cmds_ensure_dev(cmds)
-
- cmds:add({
- cmdline = "${root}${ECHO} 'g c${cyl} h${head} s${sec}' >${tmp}new.fdisk",
- replacements = {
- cyl = cyl,
- head = head,
- sec = sec
- }
- })
-
- i = 1
- while i <= 4 do
- local sysid, start, size = 0, 0, 0
-
- pd = dd:get_part_by_number(i)
- if pd then
- sysid = pd:get_sysid()
- start = pd:get_start()
- size = pd:get_size()
- if pd:is_active() then
- active_part_no = pd:get_number()
- end
- end
-
- cmds:add({
- cmdline = "${root}${ECHO} 'p ${number} ${sysid} ${start} ${size}' >>${tmp}new.fdisk",
- replacements = {
- number = i,
- sysid = sysid,
- start = start,
- size = size
- }
- })
-
- i = i + 1
- end
-
- if active_part_no then
- cmds:add({
- cmdline = "${root}${ECHO} 'a ${number}' >>${tmp}new.fdisk",
- replacements = {
- number = active_part_no
- }
- })
- end
-
- cmds:add("${root}${CAT} ${tmp}new.fdisk")
-
- App.register_tmpfile("new.fdisk")
-
- --
- -- Execute the fdisk script.
- --
- cmds:add("${root}${FDISK} -v -f ${tmp}new.fdisk " ..
- dd:get_raw_device_name())
- end
-
- dd.cmds_install_bootblock = function(dd, cmds, packet_mode)
- local o = " "
- if packet_mode then
- o = "-o packet "
- end
- cmds:add(
- {
- cmdline = "${root}${BOOT0CFG} -B " ..
- o .. dd:get_raw_device_name(),
- failure = CmdChain.FAILURE_WARN,
- tag = dd
- },
- {
- cmdline = "${root}${BOOT0CFG} -v " ..
- dd:get_raw_device_name(),
- failure = CmdChain.FAILURE_WARN,
- tag = dd
- }
- )
- end
-
- dd.cmds_wipe_start = function(dd, cmds)
- dd:cmds_ensure_dev(cmds)
- cmds:add("${root}${DD} if=${root}dev/zero of=${root}dev/" ..
- dd:get_raw_device_name() .. " bs=32k count=16")
- end
-
- dd.dump = function(dd)
- local part_no
-
- print("\t" .. name .. ": " .. cyl .. "/" .. head .. "/" .. sec .. ": " .. desc)
- for part_no in part do
- part[part_no]:dump()
- end
- end
-
- -- 'Constructor' - initialize our private state.
- -- Try to find out what we can about ourselves from fdisk.
-
- local pty, line, found, len
-
- -- Get the geometry from 'fdisk'.
- pty = Pty.open(App.expand("${root}${FDISK} " .. name))
- line = pty:readline()
- while line and not found do
- found = string.find(line, "^%s*parameters to be used for BIOS")
- line = pty:readline()
- end
-
- if found then
- found, len, cyl, head, sec =
- string.find(line, "^%s*cylinders=(%d+)%s*heads=(%d+)%s*" ..
- "sectors/track=(%d+)")
- cyl = tonumber(cyl)
- head = tonumber(head)
- sec = tonumber(sec)
- end
- pty:close()
-
- if not found then
- App.log("Warning! Could not determine geometry of disk " .. name .. "!")
- return nil
- end
-
- App.log("New Disk: " .. name .. ": " .. cyl .. "/" .. head .. "/" .. sec)
-
- -- Get the partitions from 'fdisk -s'.
- pty = Pty.open(App.expand("${root}${FDISK} -s " .. name))
- line = pty:readline() -- geometry - we already have it
- line = pty:readline() -- headings, just ignore
- line = pty:readline()
- while line do
- local part_no, start, size, sysid, flags
- found, len, part_no, start, size, sysid, flags =
- string.find(line, "^%s*(%d+):%s*(%d+)%s*(%d+)" ..
- "%s*0x(%x+)%s*0x(%x+)%s*$")
- if found then
- part_no = tonumber(part_no)
- part[part_no] = PartitionDescriptor.new{
- parent = dd,
- number = part_no,
- start = tonumber(start),
- size = tonumber(size),
- sysid = tonumber(sysid, 16),
- flags = tonumber(flags, 16)
- }
- end
- line = pty:readline()
- end
- pty:close()
-
- return dd
-end
-
---[[---------------------]]--
---[[ PartitionDescriptor ]]--
---[[---------------------]]--
-
-PartitionDescriptor = {}
-PartitionDescriptor.new = function(params)
- local pd = {} -- instance variable
- local subpart = {} -- subpartitions on this partition
-
- local parent = assert(params.parent)
- local number = assert(params.number)
- local start = assert(params.start)
- local size = assert(params.size)
- local sysid = assert(params.sysid)
- local flags = params.flags
- if params.active ~= nil then
- if params.active then
- flags = 256
- else
- flags = 0
- end
- end
- assert(type(flags) == "number")
-
- -- First set up this object's interface functions
-
- pd.get_parent = function(pd)
- return parent
- end
-
- pd.get_number = function(pd)
- return number
- end
-
- pd.get_params = function(pd)
- return start, size, sysid, flags
- end
-
- pd.get_start = function(pd)
- return start
- end
-
- pd.get_size = function(pd)
- return size
- end
-
- pd.get_sysid = function(pd)
- return sysid
- end
-
- pd.get_flags = function(pd)
- return flags
- end
-
- -- 'size' is the partition size, in blocks.
- -- return the partition's capacity in megabytes.
- pd.get_capacity = function(pd)
- return math.floor(size / 2048)
- end
-
- pd.is_active = function(pd)
- return Bitwise.bw_and(flags, 256) == 256
- end
-
- pd.get_desc = function(pd)
- return tostring(number) .. ": " ..
- tostring(pd:get_capacity()) .. "M (" ..
- tostring(start) .. "-" .. tostring(start + size) ..
- ") id=" .. sysid
- end
-
- pd.get_device_name = function(pd)
- return parent.get_name() .. "s" .. number
- end
-
- pd.get_raw_device_name = function(pd)
- -- XXX depends on operating system
- return parent.get_name() .. "s" .. number -- .. "c"
- end
-
- pd.get_activated_swap = function(pd) -- in megabytes
- local pty, line
- local swap = 0
- local found, len, devname, amount
-
- pty = Pty.open(App.expand("${root}${SWAPINFO} -k"))
- line = pty:readline()
- while line do
- if not string.find(line, "^Device") then
- found, len, devname, amount =
- string.find(line, "^([^%s]+)%s+(%d+)")
- if string.find(devname, pd:get_device_name()) then
- swap = swap + tonumber(amount)
- end
- end
- line = pty:readline()
- end
- pty:close()
-
- return math.floor(swap / 1024)
- end
-
- -- Return an iterator which yields the next next
- -- PartitionDescriptor object in this DiskDescriptor
- -- each time it is called (typically in a for loop.)
- pd.get_subparts = function(pd)
- local letter, spd
- local list = {}
- local i, n = 0, 0
-
- for letter, spd in subpart do
- table.insert(list, spd)
- end
-
- table.sort(list, function(a, b)
- -- not sure why we ever get a nil here, but we do:
- if not a and not b then return false end
-
- return a:get_letter() < b:get_letter()
- end)
-
- n = table.getn(list)
-
- return function()
- if i <= n then
- i = i + 1
- return list[i]
- end
- end
- end
-
- pd.clear_subparts = function(pd)
- subpart = {}
- end
-
- pd.add_subpart = function(pd, spd)
- subpart[spd:get_letter()] = spd
- -- spd:set_parent(pd)
- end
-
- pd.get_subpart_by_letter = function(pd, letter)
- return subpart[letter]
- end
-
- pd.get_subpart_by_mountpoint = function(pd, mountpoint)
- local letter, spd
-
- for letter, spd in subpart do
- if spd:get_mountpoint() == mountpoint then
- return spd
- end
- end
-
- return nil
- end
-
- pd.get_subpart_by_device_name = function(pd, device_name)
- local letter, spd
-
- -- Strip any leading /dev/ or whatever.
- device_name = FileName.basename(device_name)
-
- for letter, spd in subpart do
- if spd:get_device_name() == device_name then
- return spd
- end
- end
-
- return nil
- end
-
- --
- -- Determine whether any subpartition of this
- -- partition is mounted somewhere in the filesystem.
- --
- pd.is_mounted = function(pd)
- local fs_descs = MountPoints.enumerate()
- local i, fs_desc, dev_name
-
- dev_name = pd:get_device_name()
- for i, fs_desc in fs_descs do
- if string.find(fs_desc.device, dev_name, 1, true) then
- return true
- end
- end
-
- return false
- end
-
- --
- -- Methods to add appropriate commands to CmdChains.
- --
-
- -- Commands to ensure this device exists.
- pd.cmds_ensure_dev = function(pd, cmds)
- cmds:add({
- cmdline = "cd ${root}dev && ${root}${TEST_DEV} ${dev} || " ..
- "${root}${SH} MAKEDEV ${dev}",
- replacements = {
- dev = FileName.basename(pd:get_device_name())
- }
- })
- end
-
- -- Commands to format this partition.
- pd.cmds_format = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
-
- -- The information in parent NEEDS to be accurate here!
- -- Presumably we just did a survey_storage() recently.
-
- --
- -- Set the slice's sysid to 165.
- --
-
- local cyl, head, sec = parent:get_geometry()
- local start, size, sysid, flags = pd:get_params()
-
- cmds:set_replacements{
- cyl = cyl,
- head = head,
- sec = sec,
- number = pd:get_number(),
- sysid = 165,
- start = start,
- size = size,
- dev = pd:get_raw_device_name(),
- parent_dev = parent:get_raw_device_name()
- }
-
- cmds:add(
- "${root}${ECHO} 'g c${cyl} h${head} s${sec}' >${tmp}new.fdisk",
- "${root}${ECHO} 'p ${number} ${sysid} ${start} ${size}' >>${tmp}new.fdisk"
- )
-
- if pd:is_active() then
- cmds:add("${root}${ECHO} 'a ${number}' >>${tmp}new.fdisk")
- end
-
- App.register_tmpfile("new.fdisk")
-
- --
- -- Dump the fdisk script to the log for debugging.
- -- Execute the fdisk script
- -- Auto-disklabel the slice.
- -- Remove any old disklabel that might be hanging around.
- --
- cmds:add(
- "${root}${CAT} ${tmp}new.fdisk",
- "${root}${FDISK} -v -f ${tmp}new.fdisk ${parent_dev}",
- "${root}${DISKLABEL} -B -r -w ${dev} auto",
- "${root}${RM} -f ${tmp}install.disklabel.${parent_dev}"
- )
- end
-
- pd.cmds_wipe_start = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
- cmds:add(
- "${root}${DD} if=${root}dev/zero of=${root}dev/" ..
- pd:get_raw_device_name() .. " bs=32k count=16"
- )
- end
-
- pd.cmds_install_bootstrap = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
- --
- -- NB: one cannot use "/dev/adXsY" here -
- -- it must be in the form "adXsY".
- --
- cmds:add(
- "${root}${DISKLABEL} -B " ..
- pd:get_raw_device_name()
- )
- return cmds
- end
-
- pd.cmds_disklabel = function(pd, cmds)
- -- Disklabel the given partition with the
- -- subpartitions attached to it.
-
- local num_parts = 8
- if App.os.name == "DragonFly" then
- num_parts = 16
- end
-
- cmds:set_replacements{
- part = pd:get_device_name(),
- num_parts = tostring(num_parts)
- }
-
- if not FileName.is_file(App.dir.tmp .. "install.disklabel" .. pd:get_device_name()) then
- --
- -- Get a copy of the 'virgin' disklabel.
- -- XXX It might make more sense for this to
- -- happen right after format_slice() instead.
- --
- cmds:add("${root}${DISKLABEL} -r ${part} >${tmp}install.disklabel.${part}")
- end
-
- --
- -- Weave together a new disklabel out the of the 'virgin'
- -- disklabel, and the user's subpartition choices.
- --
-
- --
- -- Take everything from the 'virgin' disklabel up until the
- -- '8 or 16 partitions' line, which looks like:
- --
- -- 8 or 16 partitions:
- -- # size offset fstype [fsize bsize bps/cpg]
- -- c: 2128833 0 unused 0 0 # (Cyl. 0 - 2111*)
- --
-
- cmds:add(
- "${root}${AWK} '$2==\"partitions:\" || cut { cut = 1 } !cut { print $0 }' " ..
- "<${tmp}install.disklabel.${part} >${tmp}install.disklabel",
- "${root}${ECHO} '${num_parts} partitions:' >>${tmp}install.disklabel",
- "${root}${ECHO} '# size offset fstype [fsize bsize bps/cpg]' " ..
- ">>${tmp}install.disklabel"
- )
-
- --
- -- Write a line for each subpartition the user wants.
- --
-
- local spd = nil
- local copied_original = false
-
- for spd in pd:get_subparts() do
- if spd:get_letter() > "c" and not copied_original then
- --
- -- Copy the 'c' line from the 'virgin' disklabel.
- --
- cmds:add("${root}${GREP} '^ c:' ${tmp}install.disklabel.${part} " ..
- ">>${tmp}install.disklabel")
- copied_original = true
- end
-
- cmds:set_replacements{
- letter = spd:get_letter(),
- fsize = spd:get_fsize(),
- bsize = spd:get_bsize()
- }
-
- if spd:get_letter() == "a" then
- cmds:set_replacements{ offset = "0" }
- else
- cmds:set_replacements{ offset = "*" }
- end
- if spd:get_size() == -1 then
- cmds:set_replacements{ size = "*" }
- else
- cmds:set_replacements{ size = tostring(spd:get_size()) }
- end
-
- if spd:is_swap() then
- cmds:add("${root}${ECHO} ' ${letter}:\t${size}\t*\tswap' >>${tmp}install.disklabel")
- else
- cmds:add("${root}${ECHO} ' ${letter}:\t${size}\t${offset}\t4.2BSD\t${fsize}\t${bsize}\t99' >>${tmp}install.disklabel")
- end
- end
-
- if not copied_original then
- --
- -- Copy the 'c' line from the 'virgin' disklabel,
- -- if we haven't yet (less than 2 subpartitions.)
- --
- cmds:add("${root}${GREP} '^ c:' ${tmp}install.disklabel.${part} >>${tmp}install.disklabel")
- end
-
- App.register_tmpfile("install.disklabel")
-
- --
- -- Label the slice from the disklabel we just wove together.
- --
- -- Then create a snapshot of the disklabel we just created
- -- for debugging inspection in the log.
- --
- cmds:add(
- "${root}${DISKLABEL} -R -B -r ${part} ${tmp}install.disklabel",
- "${root}${DISKLABEL} ${part}"
- )
-
- --
- -- Create filesystems on the newly-created subpartitions.
- --
- pd:get_parent():cmds_ensure_dev(cmds)
- pd:cmds_ensure_dev(cmds)
-
- for spd in pd:get_subparts() do
- if not spd:is_swap() then
- spd:cmds_ensure_dev(cmds)
-
- if spd:is_softupdated() then
- cmds:add("${root}${NEWFS} -U ${root}dev/" ..
- spd:get_device_name())
- else
- cmds:add("${root}${NEWFS} ${root}dev/" ..
- spd:get_device_name())
- end
- end
- end
- end
-
- pd.cmds_write_fstab = function(pd, cmds, filename)
- -- Write a new fstab for the given partition
- -- to the given filename.
-
- if not filename then
- filename = "${root}mnt/etc/fstab"
- end
-
- cmds:set_replacements{
- header = "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#",
- procline = "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0",
- device = "???",
- mountpoint = "???",
- filename = App.expand(filename)
- }
-
- cmds:add("${root}${ECHO} '${header}' >${filename}")
-
- for spd in pd:get_subparts() do
- cmds:set_replacements{
- device = spd:get_device_name(),
- mountpoint = spd:get_mountpoint()
- }
-
- if spd:get_mountpoint() == "/" then
- cmds:add("${root}${ECHO} '/dev/${device}\t\t${mountpoint}\t\tufs\trw\t\t1\t1' >>${filename}")
- elseif spd:is_swap() then
- cmds:add("${root}${ECHO} '/dev/${device}\t\tnone\t\tswap\tsw\t\t0\t0' >>${filename}")
- else
- cmds:add("${root}${ECHO} '/dev/${device}\t\t${mountpoint}\t\tufs\trw\t\t2\t2' >>${filename}")
- end
- end
-
- cmds:add("${root}${ECHO} '${procline}' >>${filename}")
- end
-
- pd.dump = function(pd)
- local letter, spd
-
- print("\t\tPartition " .. number .. ": " ..
- start .. "," .. size .. ":" .. sysid .. "/" .. flags)
- for spd in pd:get_subparts() do
- spd:dump()
- end
- end
-
- App.log("New Partition: " .. number .. ": " ..
- start .. "," .. size .. ":" .. sysid .. "/" .. flags)
-
- -- 'Constructor' - initialize this object's state.
- -- If this looks like a BSD slice, try to probe it with
- -- disklabel to get an idea of the subpartitions on it.
-
- local pty, line, found, len
- local letter, size, offset, fstype, fsize, bsize
-
- if sysid == 165 then
- pty = Pty.open(App.expand("${root}${DISKLABEL} " .. parent:get_name() ..
- "s" .. number))
- line = pty:readline()
- found = false
- while line and not found do
- found = string.find(line, "^%d+%s+partitions:")
- line = pty:readline()
- end
- if found then
- while line do
- found, len, letter, size, offset, fstype,
- fsize, bsize = string.find(line,
- "^%s*(%a):%s*(%d+)%s*(%d+)%s*([^%s]+)")
- if found then
- fsize, bsize = 0, 0
- if fstype == "4.2BSD" then
- found, len, letter, size,
- offset, fstype, fsize,
- bsize = string.find(line,
- "^%s*(%a):%s*(%d+)%s*" ..
- "(%d+)%s*([^%s]+)%s*" ..
- "(%d+)%s*(%d+)")
- end
- subpart[letter] =
- SubpartitionDescriptor.new{
- parent = pd,
- letter = letter,
- size = size,
- offset = offset,
- fstype = fstype,
- fsize = fsize,
- bsize = bsize
- }
- end
- line = pty:readline()
- end
- end
-
- pty:close()
- end
-
- return pd
-end
-
---[[------------------------]]--
---[[ SubpartitionDescriptor ]]--
---[[------------------------]]--
-
-SubpartitionDescriptor = {}
-SubpartitionDescriptor.new = function(params)
- local spd = {} -- instance variable
-
- local parent = assert(params.parent)
- local letter = assert(params.letter)
- local size = assert(params.size)
- local offset = assert(params.offset)
- local fstype = assert(params.fstype)
- local fsize = assert(params.fsize)
- local bsize = assert(params.bsize)
- local mountpoint = params.mountpoint
-
- -- Now set up this object's interface functions
-
- spd.get_parent = function(spd)
- return parent
- end
-
- spd.get_letter = function(spd)
- return letter
- end
-
- spd.set_mountpoint = function(spd, new_mountpoint)
- mountpoint = new_mountpoint
- end
-
- spd.get_mountpoint = function(spd)
- return mountpoint
- end
-
- spd.get_fstype = function(spd)
- return fstype
- end
-
- spd.get_device_name = function(spd)
- return parent.get_parent().get_name() ..
- "s" .. parent.get_number() .. letter
- end
-
- spd.get_raw_device_name = function(spd)
- -- XXX depends on operating system
- return parent.get_parent().get_name() ..
- "s" .. parent.get_number() .. letter
- end
-
- spd.get_capacity = function(spd) -- in megabytes
- return math.floor(size / 2048)
- end
-
- spd.get_size = function(spd) -- in sectors
- return size
- end
-
- spd.get_fsize = function(spd)
- return fsize
- end
-
- spd.get_bsize = function(spd)
- return bsize
- end
-
- spd.is_swap = function(spd)
- return fstype == "swap"
- end
-
- spd.is_softupdated = function(spd)
- -- XXX this should be a property
- return mountpoint ~= "/"
- end
-
- spd.dump = function(pd)
- print("\t\t\t" .. letter .. ": " .. offset .. "," .. size ..
- ": " .. fstype .. " -> " .. mountpoint)
- end
-
- -- Commands to ensure this device exists.
- spd.cmds_ensure_dev = function(spd, cmds)
- cmds:add({
- cmdline = "cd ${root}dev && ${root}${TEST_DEV} ${dev} || " ..
- "${root}${SH} MAKEDEV ${dev}",
- replacements = {
- dev = FileName.basename(spd:get_device_name())
- }
- })
- end
-
- --
- -- Constructor.
- --
-
- App.log("New Subpartition on " .. parent:get_device_name() .. ": " ..
- letter .. ": " .. offset .. "," .. size .. ": " .. fstype ..
- " F=" .. fsize .. ", B=" .. bsize)
-
- return spd
-end
-
--- END of lib/storage.lua --
+++ /dev/null
--- $Id: CmdChain.lua,v 1.33 2005/03/26 23:36:13 cpressey Exp $
-
-require "app"
-
---[[-----------]]--
---[[ CmdChains ]]--
---[[-----------]]--
-
--- Global "class" variable:
-CmdChain = {}
-
--- Some 'symbolic constants':
-CmdChain.LOG_SILENT = {}
-CmdChain.LOG_QUIET = {}
-CmdChain.LOG_VERBOSE = {}
-
-CmdChain.FAILURE_IGNORE = {}
-CmdChain.FAILURE_WARN = {}
-CmdChain.FAILURE_ABORT = {}
-
-CmdChain.RESULT_NEVER_EXECUTED = {}
-CmdChain.RESULT_POPEN_ERROR = {}
-CmdChain.RESULT_SELECT_ERROR = {}
-CmdChain.RESULT_CANCELLED = {}
-CmdChain.RESULT_SKIPPED = {}
-
--- Create a new command chain object instance.
-CmdChain.new = function(...)
- local chain = {}
- local cmds = {}
- local capture = {}
- local replacements = {}
-
- --
- -- Private functions.
- --
-
- -- Fix up a command descriptor. If it is just a string, turn
- -- it into a table; fill out any missing default values in the
- -- table; and expand the string as appropriate.
- local fix_cmd = function(cmd)
- if type(cmd) == "string" then
- cmd = { cmdline = cmd }
- end
- assert(type(cmd) == "table")
-
- if cmd.cmdline == nil then
- cmd.cmdline = ""
- end
- assert(type(cmd.cmdline) == "string")
-
- if cmd.log_mode == nil then
- cmd.log_mode = CmdChain.LOG_VERBOSE
- end
- assert(cmd.log_mode == CmdChain.LOG_SILENT or
- cmd.log_mode == CmdChain.LOG_QUIET or
- cmd.log_mode == CmdChain.LOG_VERBOSE)
-
- if cmd.failure_mode == nil then
- cmd.failure_mode = CmdChain.FAILURE_ABORT
- end
- assert(cmd.failure_mode == CmdChain.FAILURE_IGNORE or
- cmd.failure_mode == CmdChain.FAILURE_WARN or
- cmd.failure_mode == CmdChain.FAILURE_ABORT)
-
- if cmd.replacements == nil then
- cmd.replacements = {}
- end
- assert(type(cmd.replacements) == "table")
-
- cmd.cmdline = App.expand(cmd.cmdline,
- cmd.replacements, replacements)
-
- cmd.display_cmdline = cmd.cmdline
-
- if cmd.on_executed ~= nil then
- assert(type(cmd.on_executed) == "function")
- end
-
- -- cmd.desc, cmd.tag, cmd.sensitive, cmd.on_executed,
- -- and cmd.input are left as nil if not specified.
-
- return cmd
- end
-
- -- Open a stream to a command to be executed, read from it,
- -- and update the progress bar as data comes and (and/or as the
- -- read from the stream times out.)
-
- -- Returns:
- -- - the return value of the command on the other end of the stream;
- -- - a boolean indicating whether it was cancelled by the user; and
- -- - the output of the command, if requested (cmd.capture.)
-
- local stream_loop = function(pr, cmd)
- local done = false
- local cancelled = false
- local pty
- local output = {}
- local cmdline
-
- local escape = function(pat)
- return string.gsub(pat, "([^%w])", "%%%1")
- end
-
- cmdline = "(" .. cmd.cmdline .. ") 2>&1"
- if not cmd.input then
- cmdline = cmdline .. " </dev/null"
- end
- pty = Pty.open(cmdline)
- if not pty then
- App.log("! could not open pty to: " .. cmd.cmdline)
- return CmdChain.RESULT_POPEN_ERROR, false, output
- end
- if cmd.input then
- pty:write(cmd.input)
- pty:flush()
- end
-
- while not done do
- if cancelled then break end
- line, err = pty:readline(1000)
-
- if line then
- if cmd.sensitive ~= nil then
- assert(type(cmd.sensitive) == "string")
- line = string.gsub(
- line, escape(cmd.sensitive), "***not*shown***"
- )
- end
- cancelled = not pr:update()
- if cmd.log_mode == CmdChain.LOG_VERBOSE then
- App.log("| " .. line)
- elseif cmd.log_mode == CmdChain.LOG_QUIET then
- io.stderr:write("| " .. line .. "\n")
- else -- cmd.log_mode == CmdChain.LOG_SILENT
- -- do nothing
- end
- if cmd.capture then
- table.insert(output, line)
- end
- else
- if err == Pty.TIMEOUT then
- cancelled = not pr:update()
- elseif err == Pty.EOF then
- break
- else
- App.log("! pty:read() failed, err=%d", err)
- pty:close()
- return CmdChain.RESULT_SELECT_ERROR,
- false, output;
- end
- end
- end
-
- if cancelled then
- pty:signal(Pty.SIGTERM)
- end
-
- return pty:close(), cancelled, output
- end
-
- local interruption_dialog = function(cmd, cancelled, result)
- local done_interruption = false
- local done_command = false
- local msg
-
- if cancelled then
- msg = "was cancelled."
- else
- msg = "FAILED with a return code of " .. tostring(result) .. "."
- end
-
- while not done_interruption do
- App.ui:present({
- id = "cancelled",
- name = "Cancelled",
- short_desc = "Execution of the command\n\n" ..
- cmd.display_cmdline .. "\n\n" .. msg,
- actions = {
- {
- id = "view_log",
- name = "View Log",
- short_desc = "View the command output that led up to this",
- effect = function()
- App.view_log()
- end
- },
- {
- id = "retry",
- name = "Retry",
- short_desc = "Try executing this command again",
- effect = function()
- done_interruption = true
- end
- },
- {
- id = "cancel",
- name = "Cancel",
- short_desc = "Abort this sequence of commands",
- effect = function()
- result = CmdChain.RESULT_CANCELLED
- done_interruption = true
- done_command = true
- end
- },
- {
- id = "skip",
- name = "Skip",
- short_desc = "Skip this particular command and resume with the next one",
- effect = function()
- result = CmdChain.RESULT_SKIPPED
- done_interruption = true
- done_command = true
- end
- }
- }
- })
- end
-
- return done_command, result
- end
-
- -- Execute a single command.
- -- Return values are:
- -- - a COMMAND_RESULT_* constant, or a value from 0 to 255
- -- to indicate the exit code from the utility; and
- -- - the output of the command, if requested (cmd.capture.)
-
- local command_execute = function(pr, cmd)
- local filename
- local cancelled = false
- local done_command = false
- local result, output = CmdChain.RESULT_NEVER_EXECUTED, ""
-
- if cmd.desc then
- pr:set_short_desc(cmd.desc)
- else
- pr:set_short_desc(cmd.display_cmdline)
- end
- cancelled = not pr:update()
-
- if App.option.confirm_execution then
- done_command = not App.ui:confirm(
- "About to execute:\n\n" .. cmd.display_cmdline ..
- "\n\nIs this acceptable?"
- )
- end
-
- while not done_command do
- output = nil
- if cmd.log_mode ~= CmdChain.LOG_SILENT then
- App.log(",-<<< Executing `" .. cmd.display_cmdline .. "'")
- end
- if App.option.fake_execution then
- if cmd.log_mode ~= CmdChain.LOG_SILENT then
- App.log("| (not actually executed)")
- end
- result = 0
- else
- result, cancelled, output = stream_loop(pr, cmd)
- end
- if cmd.log_mode ~= CmdChain.LOG_SILENT then
- App.log("`->>> Exit status: " .. tostring(result))
- end
-
- if cancelled then
- pr:stop()
- done_command, result = interruption_dialog(cmd, cancelled, result)
- pr:start()
- elseif cmd.failure_mode == CmdChain.FAILURE_IGNORE then
- result = 0
- done_command = true
- elseif (result ~= 0 and cmd.failure_mode ~= CmdChain.FAILURE_WARN) then
- pr:stop()
- done_command, result = interruption_dialog(cmd, cancelled, result)
- pr:start()
- else
- done_command = true
- end
- end
- if cmd.on_executed ~= nil then
- cmd.on_executed(cmd, result, output)
- end
-
- return result, output
- end
-
- --
- -- Methods.
- --
-
- --
- -- Set the global replacements for this command chain.
- -- These will be applied to each command that is
- -- subsequently added (although local replacements will
- -- be applied first.)
- --
- chain.set_replacements = function(cmd, new_replacements)
- App.merge_tables(replacements, new_replacements,
- function(key, dest_val, src_val)
- return src_val
- end)
- end
-
- --
- -- Get captured output by its id.
- --
- chain.get_output = function(cmd, cap_id)
- return capture[cap_id]
- end
-
- --
- -- Add one or more commands to this command chain.
- --
- chain.add = function(chain, ...)
- local cmd_no, cmd
-
- if table.getn(arg) == 0 then
- return
- end
-
- for cmd_no, cmd in ipairs(arg) do
- table.insert(cmds, fix_cmd(cmd))
- end
- end
-
- -- Execute a series of external utility programs.
- -- Returns 1 if everything executed OK, 0 if one of the
- -- critical commands failed or if the user cancelled.
- chain.execute = function(chain)
- local pr
- local cmd
- local i, n, result = 0, 0, 0
- local return_val = true
- local output
-
- n = table.getn(cmds)
-
- pr = App.ui:new_progress_bar{
- title = "Executing Commands"
- }
-
- pr:start()
-
- for i in cmds do
- result, output = command_execute(pr, cmds[i])
- if result == CmdChain.RESULT_CANCELLED then
- return_val = false
- break
- end
- if type(result) == "number" and result > 0 and result < 256 then
- return_val = false
- if cmd.failure_mode == CmdChain.FAILURE_ABORT then
- break
- end
- end
- if cmds[i].capture then
- capture[cmds[i].capture] = output
- end
- pr:set_amount((i * 100) / n)
- end
-
- pr:stop()
-
- return return_val
- end
-
- -- Show the commands that have been added to this
- -- command chain to the user in a dialog box.
- chain.preview = function(chain)
- local contents = ""
- local i, cmd
-
- for i, cmd in cmds do
- contents = contents .. cmd.cmdline .. "\n"
- end
-
- App.ui:present({
- id = "cmd_preview",
- name = "Command Preview",
- short_desc = contents,
- role = "informative",
- minimum_width = "72",
- monospaced = "true",
- actions = {
- { id = "ok", name = "OK" }
- }
- })
- end
-
- -- Record these commands in a shell script file.
- chain.record = function(chain, file)
- local contents = ""
- local i, cmd
-
- local gen_rand_string = function(len)
- local n = 1
- local s = ""
- local A = string.byte("A")
- assert(len >= 0)
-
- while n <= len do
- s = s .. string.char(math.random(A, A + 25))
- n = n + 1
- end
-
- return s
- end
-
- local get_marker_for = function(text)
- local s
-
- s = gen_rand_string(5)
- while string.find(text, s, 1, true) do
- s = gen_rand_string(5)
- end
- return s
- end
-
- for i, cmd in cmds do
- --
- -- Write lines apropos to the cmdline being
- -- executed, taking in account the failure mode.
- --
- if cmd.failure_mode == CmdChain.FAILURE_IGNORE then
- file:write(cmd.cmdline)
- elseif cmd.failure_mode == CmdChain.FAILURE_WARN then
- file:write("(" .. cmd.cmdline .. " || " ..
- "echo \"WARNING: " .. cmd.cmdline ..
- " failed with exit code $?\")")
- elseif cmd.failure_mode == CmdChain.FAILURE_ABORT then
- file:write(cmd.cmdline)
- end
-
- --
- -- If the command has input, include that as a heredoc.
-
- if cmd.input then
- local marker = get_marker_for(cmd.input)
- file:write(" <<" .. marker .. "\n" .. cmd.input .. marker)
- end
-
- if cmd.failure_mode == CmdChain.FAILURE_WARN or
- cmd.failure_mode == CmdChain.FAILURE_ABORT then
- file:write(" && \\")
- end
-
- --
- -- Write the description as a comment following.
- --
- if cmd.desc then
- file:write(" # " .. cmd.desc)
- end
-
- file:write("\n")
- end
- end
-
- -- ``Constructor'' - initialize our instance data.
-
- if table.getn(arg) > 0 then
- chain:add(unpack(arg))
- end
-
- return chain
-end
+++ /dev/null
--- $Id: ConfigFile.lua,v 1.1 2004/11/28 03:52:05 cpressey Exp $
-
-require "app"
-require "cmdchain"
-
---[[------------]]--
---[[ ConfigVars ]]--
---[[------------]]--
-
-ConfigVars = {}
-ConfigVars.new = function()
- local cv = {}
- local var = {}
-
- cv.get = function(cv, name)
- return var[name]
- end
-
- cv.set = function(cv, name, value)
- var[name] = value
- end
-
- --
- -- Populate this set of variables from a file.
- --
- -- This isn't perfect. It doesn't handle variables
- -- with embedded newlines, for example. It also
- -- has to execute the script, which is undesirable.
- --
- cv.read = function(cv, filename, filetype)
- local cmds = CmdChain.new()
- local diff, i
-
- cmds:add(
- "set | ${root}${SORT} >${tmp}env.before",
- {
- cmdline = ". ${filename} && set | ${root}${SORT} >${tmp}env.after",
- replacements = {
- filename = filename
- }
- },
- {
- cmdline = "${root}${COMM} -1 -3 ${tmp}env.before ${tmp}env.after",
- capture = "comm"
- },
- "${root}${RM} -f ${tmp}env.before ${tmp}env.after"
- )
-
- if not cmds:execute() then
- return false
- end
-
- diff = cmds:get_output("comm")
- for i in diff do
- local found, ends, k, v
-
- found, ends, k, v =
- string.find(diff[i], "^([^=]+)='(.*)'$")
- if found then
- cv:set(k, v)
- else
- found, ends, k, v =
- string.find(diff[i], "^([^=]+)=(.*)$")
- if found then
- cv:set(k, v)
- end
- end
- end
-
- return true
- end
-
- -- Write this set of configuration variable settings to a file.
- cv.write = function(cv, filename, filetype)
- local k, v
- local file = io.open(filename, "a")
- local written = false
-
- if not file then
- return false
- end
-
- for k, v in var do
- if not written then
- written = true
- file:write("\n")
- file:write("# -- BEGIN BSD Installer automatically generated configuration -- #\n")
- file:write("# -- Written on " .. os.date() .. " -- #\n")
- end
-
- file:write(k .. "='" .. v.. "'\n")
- end
-
- if written then
- file:write("# -- END of BSD Installer " ..
- "automatically generated configuration -- #\n")
- end
-
- file:close()
-
- return true
- end
-
- return cv
-end
+++ /dev/null
--- lib/storage.lua
--- $Id: Disk.lua,v 1.76 2005/03/29 21:04:19 cpressey Exp $
--- Storage Descriptors (a la libinstaller) in Lua.
-
--- BEGIN lib/storage.lua --
-
-local App = require("app")
-local FileName = require("filename")
-require "cmdchain"
-require "bitwise"
-require "mountpoint"
-
---
--- Note: these methods should try to use consistent terminology:
---
--- 'capacity' of an object refers to its capacity in megabytes.
--- 'size' of an object refers to its size in blocks or sectors
--- (which are assumed to be 512 bytes each.)
--- 'capstring' refers to a string which includes a unit suffix:
--- 'M' for megabytes
--- 'G' for gigabytes
--- '*' to indicate 'use the remaining space on the device'
---
-
---[[-------------------]]--
---[[ StorageDescriptor ]]--
---[[-------------------]]--
-
--- This class returns an object which can represent
--- the system's data storage capabilities.
-
-StorageDescriptor = {}
-StorageDescriptor.new = function()
- local disk = {} -- disks in this storage descriptor
- local ram = 0 -- in megabytes
- local sd = {} -- instance variable
-
- -- Internal function.
- local next_power_of_two = function(n)
- local i = 1
- n = math.ceil(n)
-
- while i < n and i >= 1 do
- i = i * 2
- end
-
- if i > n then
- return i
- else
- return n
- end
- end
-
- -- Now set up this object's interface functions
-
- -- Look through `dmesg', `atacontrol list', etc, and
- -- populate disks and ram with values
- -- that are as accurate and readable as possible.
- -- XXX not yet fully implemented.
- sd.survey = function(sd)
- local pty, line
- local disk_name, dd
- local cmd
- local found, len, cap
-
- cmd = App.expand("${root}${SYSCTL} -n hw.physmem")
- pty = Pty.open(cmd)
- line = pty:readline()
- pty:close()
-
- App.log("`" .. cmd .. "` returned: " .. line)
-
- ram = next_power_of_two(tonumber(line) / (1024 * 1024))
-
- cmd = App.expand("${root}${SYSCTL} -n kern.disks")
- pty = Pty.open(cmd)
- line = pty:readline()
- pty:close()
-
- App.log("`" .. cmd .. "` returned: " .. line)
-
- for disk_name in string.gfind(line, "%s*(%w+)") do
- if not string.find(disk_name, "^md") then
- disk[disk_name] = DiskDescriptor.new(sd, disk_name)
- end
- end
-
- for line in io.lines("/var/run/dmesg.boot") do
- for disk_name, dd in disk do
- found, len, cap =
- string.find(line, "^" .. disk_name .. ":%s*(.*)$")
- if found then
- dd:set_desc(disk_name .. ": " .. cap)
- end
- end
- end
-
- cmd = App.expand("${root}${ATACONTROL} list")
- pty = Pty.open(cmd)
- line = pty:readline()
- while line do
- for disk_name, dd in disk do
- found, len, cap =
- string.find(line, "^%s*Master:%s*" ..
- disk_name .. "%s*(%<.*%>)$")
- if not found then
- found, len, cap =
- string.find(line, "^%s*Slave:%s*" ..
- disk_name .. "%s*(%<.*%>)$")
- end
- if found then
- dd:set_desc(disk_name .. ": " .. cap)
- end
- end
- line = pty:readline()
- end
- pty:close()
- end
-
- -- Refresh our view of the storage connected to the
- -- system, but remember what disk and/or partition
- -- was selected as well.
- sd.resurvey = function(sd, sel_disk, sel_part)
- local sel_disk_name, sel_part_no
-
- if sel_disk then
- sel_disk_name = sel_disk:get_name()
- end
-
- if sel_part then
- sel_part_no = sel_part:get_number()
- end
-
- sd:survey()
-
- if sel_disk then
- sel_disk = sd:get_disk_by_name(sel_disk_name)
- if not sel_disk then
- -- XXX warn that sel disk was lost!
- end
- end
-
- if sel_disk and sel_part then
- sel_part = sel_disk:find_part_by_number(sel_part_no)
- if not sel_part then
- -- XXX warn that sel part was lost!
- end
- end
-
- return sel_disk, sel_part
- end
-
- -- Return an iterator which yields the next next
- -- DiskDescriptor object in this StorageDescriptor
- -- each time it is called (typically in a for loop.)
- sd.get_disks = function(sd)
- local disk_name, dd
- local list = {}
- local i, n = 0, 0
-
- for disk_name, dd in disk do
- table.insert(list, dd)
- n = n + 1
- end
-
- table.sort(list, function(a, b)
- return a:get_name() < b:get_name()
- end)
-
- return function()
- if i <= n then
- i = i + 1
- return list[i]
- end
- end
- end
-
- -- Given the name of a disk, return that disk descriptor,
- -- or nil if no disk by that name was found.
- sd.get_disk_by_name = function(sd, name)
- local dd
-
- for dd in sd:get_disks() do
- if dd:get_name() == name then
- return dd
- end
- end
-
- return nil
- end
-
- sd.get_disk_count = function(sd)
- local disk_name, dd
- local n = 0
-
- for disk_name, dd in disk do
- n = n + 1
- end
-
- return n
- end
-
- sd.get_ram = function(sd) -- in megabytes
- return ram
- end
-
- sd.get_activated_swap = function(sd) -- in megabytes
- local pty, line
- local swap = 0
- local found, len, devname, amount
-
- pty = Pty.open(App.expand("${root}${SWAPINFO} -k"))
- line = pty:readline()
- while line do
- if not string.find(line, "^Device") then
- found, len, devname, amount =
- string.find(line, "^([^%s]+)%s+(%d+)")
- swap = swap + tonumber(amount)
- end
- line = pty:readline()
- end
- pty:close()
-
- return math.floor(swap / 1024)
- end
-
- sd.dump = function(sd)
- local disk_name, dd
-
- print("*** DUMP of StorageDescriptor ***")
- for disk_name, dd in disk do
- dd:dump()
- end
- end
-
- return sd
-end
-
---
--- The following global static utility functions in the
--- StorageDescriptor class are really human interface functions;
--- they might be better placed elsewhere.
---
-
---
--- Take a capstring and return a number indicating size in blocks.
--- If the capstring is "*", the supplied remainder is returned.
--- If the capstring could not be parsed, returns nil.
---
-StorageDescriptor.parse_capstring = function(str, remainder)
- if str == "*" then
- return remainder
- else
- local suffix = string.sub(str, -1, -1)
- local body = string.sub(str, 1, string.len(str) - 1)
-
- if suffix == "G" or suffix == "g" then
- return math.floor(tonumber(body) * 1024 * 1024 * 2)
- elseif suffix == "M" or suffix == "m" then
- return math.floor(tonumber(body) * 1024 * 2)
- else
- -- bad suffix
- return nil
- end
- end
-end
-
---
--- Takes a number specifying a size in blocks and
--- convert it to a capstring.
---
-StorageDescriptor.format_capstring = function(blocks)
- if blocks >= 1024 * 1024 * 2 then
- return tostring(math.floor(blocks / (1024 * 1024 * 2) * 100) / 100) .. "G"
- else
- return tostring(math.floor(blocks / (1024 * 2) * 100) / 100) .. "M"
- end
-end
-
-
---[[----------------]]--
---[[ DiskDescriptor ]]--
---[[----------------]]--
-
-DiskDescriptor = {}
-DiskDescriptor.new = function(parent, name)
- local dd = {} -- instance variable
- local part = {} -- private: partitions on this disk
- local desc = name -- private: description of disk
- local cyl, head, sec -- private: geometry of disk
- local touched = false -- private: whether we formatted it
-
- -- Set up this object instance's interface functions first:
-
- dd.get_parent = function(dd)
- return parent
- end
-
- dd.get_name = function(dd)
- return name
- end
-
- dd.set_desc = function(dd, new_desc)
- --
- -- Calculate a score for how well this string describes
- -- a disk. Reject obviously bogus descriptions (usually
- -- erroneously harvested from error messages in dmesg.)
- --
- local calculate_score = function(s)
- local score = 0
-
- -- In the absence of any good discriminator,
- -- the longest disk description wins.
- score = string.len(s)
-
- -- Look for clues
- if string.find(s, "%d+MB") then
- score = score + 10
- end
- if string.find(s, "%<.*%>") then
- score = score + 10
- end
- if string.find(s, "%[%d+%/%d+%/%d+%]") then
- score = score + 10
- end
-
- -- Look for error messages
- if string.find(s, "resetting") then
- score = 0
- end
-
- return score
- end
-
- if calculate_score(new_desc) > calculate_score(desc) then
- desc = new_desc
- end
- end
-
- dd.get_desc = function(dd)
- return desc
- end
-
- dd.get_geometry = function(dd)
- return cyl, head, sec
- end
-
- dd.get_device_name = function(dd)
- return name
- end
-
- dd.get_raw_device_name = function(dd)
- -- XXX depends on operating system
- return name
- end
-
- -- Return an iterator which yields the next next
- -- PartitionDescriptor object in this DiskDescriptor
- -- each time it is called (typically in a for loop.)
- dd.get_parts = function(dd)
- local i, n = 0, table.getn(part)
-
- return function()
- if i <= n then
- i = i + 1
- return part[i]
- end
- end
- end
-
- -- Given the number of a partition, return that
- -- partition descriptor, or nil if not found.
- dd.get_part_by_number = function(dd, number)
- local pd
-
- for pd in dd:get_parts() do
- if pd:get_number() == number then
- return pd
- end
- end
-
- return nil
- end
-
- dd.get_part_count = function(dd)
- return table.getn(part)
- end
-
- -- return the disk's capacity in megabytes.
- -- this is actually the sum of the capacities of the
- -- partitions on this disk.
- dd.get_capacity = function(dd)
- local pd
- local cap = 0
-
- for pd in dd:get_parts() do
- cap = cap + pd:get_capacity()
- end
-
- return cap
- end
-
- -- return the disk's raw size in sectors.
- dd.get_raw_size = function(dd)
- pty = Pty.open(App.expand(
- "${root}${FDISK} -t -I " ..
- dd:get_raw_device_name()))
- line = pty:readline()
- while line do
- local found, len, start, size =
- string.find(line, "start%s*(%d+)%s*,%s*size%s*(%d+)")
- if found then
- pty:close()
- return tonumber(start) + tonumber(size)
- end
- line = pty:readline()
- end
- pty:close()
-
- return nil
- end
-
- dd.touch = function(dd)
- touched = true
- end
-
- dd.has_been_touched = function(dd)
- return touched
- end
-
- --
- -- Determine whether any subpartition from any partition of this
- -- disk is mounted somewhere in the filesystem.
- --
- dd.is_mounted = function(dd)
- local fs_descs = MountPoints.enumerate()
- local i, fs_desc, dev_name
-
- dev_name = dd:get_device_name()
- for i, fs_desc in fs_descs do
- if string.find(fs_desc.device, dev_name, 1, true) then
- return true
- end
- end
-
- return false
- end
-
- --
- -- Methods to manipulate the contents of this DiskDescriptor.
- --
-
- dd.clear_parts = function(dd)
- part = {}
- end
-
- dd.add_part = function(dd, pd)
- part[pd:get_number()] = pd
- -- pd:set_parent(dd)
- end
-
- --
- -- Methods to add appropriate commands to CmdChains.
- --
-
- -- Commands to ensure this device exists.
- dd.cmds_ensure_dev = function(dd, cmds)
- cmds:add({
- cmdline = "cd ${root}dev && ${root}${TEST_DEV} ${dev} || " ..
- "${root}${SH} MAKEDEV ${dev}",
- replacements = {
- dev = FileName.basename(dd:get_device_name())
- }
- })
- end
-
- -- Commands to format this disk.
- dd.cmds_format = function(dd, cmds)
- dd:cmds_ensure_dev(cmds)
-
- --
- -- Currently you need to pass 'yes' to OpenBSD's fdisk to
- -- be able to do these. (This is a shot in the dark:)
- --
- if App.os.name == "OpenBSD" then
- cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " ..
- "${root}${FDISK} -I " ..
- dd:get_raw_device_name())
- cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " ..
- "${root}${FDISK} -B " ..
- dd:get_raw_device_name())
- else
- cmds:add("${root}${FDISK} -I " ..
- dd:get_raw_device_name())
- cmds:add("${root}${YES} | ${root}${FDISK} -B " ..
- dd:get_raw_device_name())
- end
- end
-
- -- Commands to partition this disk.
- dd.cmds_partition = function(dd, cmds)
- local i, pd
- local active_part_no
- local cyl, head, sec = dd:get_geometry()
-
- dd:cmds_ensure_dev(cmds)
-
- cmds:add({
- cmdline = "${root}${ECHO} 'g c${cyl} h${head} s${sec}' >${tmp}new.fdisk",
- replacements = {
- cyl = cyl,
- head = head,
- sec = sec
- }
- })
-
- i = 1
- while i <= 4 do
- local sysid, start, size = 0, 0, 0
-
- pd = dd:get_part_by_number(i)
- if pd then
- sysid = pd:get_sysid()
- start = pd:get_start()
- size = pd:get_size()
- if pd:is_active() then
- active_part_no = pd:get_number()
- end
- end
-
- cmds:add({
- cmdline = "${root}${ECHO} 'p ${number} ${sysid} ${start} ${size}' >>${tmp}new.fdisk",
- replacements = {
- number = i,
- sysid = sysid,
- start = start,
- size = size
- }
- })
-
- i = i + 1
- end
-
- if active_part_no then
- cmds:add({
- cmdline = "${root}${ECHO} 'a ${number}' >>${tmp}new.fdisk",
- replacements = {
- number = active_part_no
- }
- })
- end
-
- cmds:add("${root}${CAT} ${tmp}new.fdisk")
-
- App.register_tmpfile("new.fdisk")
-
- --
- -- Execute the fdisk script.
- --
- cmds:add("${root}${FDISK} -v -f ${tmp}new.fdisk " ..
- dd:get_raw_device_name())
- end
-
- dd.cmds_install_bootblock = function(dd, cmds, packet_mode)
- local o = " "
- if packet_mode then
- o = "-o packet "
- end
- cmds:add(
- {
- cmdline = "${root}${BOOT0CFG} -B " ..
- o .. dd:get_raw_device_name(),
- failure = CmdChain.FAILURE_WARN,
- tag = dd
- },
- {
- cmdline = "${root}${BOOT0CFG} -v " ..
- dd:get_raw_device_name(),
- failure = CmdChain.FAILURE_WARN,
- tag = dd
- }
- )
- end
-
- dd.cmds_wipe_start = function(dd, cmds)
- dd:cmds_ensure_dev(cmds)
- cmds:add("${root}${DD} if=${root}dev/zero of=${root}dev/" ..
- dd:get_raw_device_name() .. " bs=32k count=16")
- end
-
- dd.dump = function(dd)
- local part_no
-
- print("\t" .. name .. ": " .. cyl .. "/" .. head .. "/" .. sec .. ": " .. desc)
- for part_no in part do
- part[part_no]:dump()
- end
- end
-
- -- 'Constructor' - initialize our private state.
- -- Try to find out what we can about ourselves from fdisk.
-
- local pty, line, found, len
-
- -- Get the geometry from 'fdisk'.
- pty = Pty.open(App.expand("${root}${FDISK} " .. name))
- line = pty:readline()
- while line and not found do
- found = string.find(line, "^%s*parameters to be used for BIOS")
- line = pty:readline()
- end
-
- if found then
- found, len, cyl, head, sec =
- string.find(line, "^%s*cylinders=(%d+)%s*heads=(%d+)%s*" ..
- "sectors/track=(%d+)")
- cyl = tonumber(cyl)
- head = tonumber(head)
- sec = tonumber(sec)
- end
- pty:close()
-
- if not found then
- App.log("Warning! Could not determine geometry of disk " .. name .. "!")
- return nil
- end
-
- App.log("New Disk: " .. name .. ": " .. cyl .. "/" .. head .. "/" .. sec)
-
- -- Get the partitions from 'fdisk -s'.
- pty = Pty.open(App.expand("${root}${FDISK} -s " .. name))
- line = pty:readline() -- geometry - we already have it
- line = pty:readline() -- headings, just ignore
- line = pty:readline()
- while line do
- local part_no, start, size, sysid, flags
- found, len, part_no, start, size, sysid, flags =
- string.find(line, "^%s*(%d+):%s*(%d+)%s*(%d+)" ..
- "%s*0x(%x+)%s*0x(%x+)%s*$")
- if found then
- part_no = tonumber(part_no)
- part[part_no] = PartitionDescriptor.new{
- parent = dd,
- number = part_no,
- start = tonumber(start),
- size = tonumber(size),
- sysid = tonumber(sysid, 16),
- flags = tonumber(flags, 16)
- }
- end
- line = pty:readline()
- end
- pty:close()
-
- return dd
-end
-
---[[---------------------]]--
---[[ PartitionDescriptor ]]--
---[[---------------------]]--
-
-PartitionDescriptor = {}
-PartitionDescriptor.new = function(params)
- local pd = {} -- instance variable
- local subpart = {} -- subpartitions on this partition
-
- local parent = assert(params.parent)
- local number = assert(params.number)
- local start = assert(params.start)
- local size = assert(params.size)
- local sysid = assert(params.sysid)
- local flags = params.flags
- if params.active ~= nil then
- if params.active then
- flags = 256
- else
- flags = 0
- end
- end
- assert(type(flags) == "number")
-
- -- First set up this object's interface functions
-
- pd.get_parent = function(pd)
- return parent
- end
-
- pd.get_number = function(pd)
- return number
- end
-
- pd.get_params = function(pd)
- return start, size, sysid, flags
- end
-
- pd.get_start = function(pd)
- return start
- end
-
- pd.get_size = function(pd)
- return size
- end
-
- pd.get_sysid = function(pd)
- return sysid
- end
-
- pd.get_flags = function(pd)
- return flags
- end
-
- -- 'size' is the partition size, in blocks.
- -- return the partition's capacity in megabytes.
- pd.get_capacity = function(pd)
- return math.floor(size / 2048)
- end
-
- pd.is_active = function(pd)
- return Bitwise.bw_and(flags, 256) == 256
- end
-
- pd.get_desc = function(pd)
- return tostring(number) .. ": " ..
- tostring(pd:get_capacity()) .. "M (" ..
- tostring(start) .. "-" .. tostring(start + size) ..
- ") id=" .. sysid
- end
-
- pd.get_device_name = function(pd)
- return parent.get_name() .. "s" .. number
- end
-
- pd.get_raw_device_name = function(pd)
- -- XXX depends on operating system
- return parent.get_name() .. "s" .. number -- .. "c"
- end
-
- pd.get_activated_swap = function(pd) -- in megabytes
- local pty, line
- local swap = 0
- local found, len, devname, amount
-
- pty = Pty.open(App.expand("${root}${SWAPINFO} -k"))
- line = pty:readline()
- while line do
- if not string.find(line, "^Device") then
- found, len, devname, amount =
- string.find(line, "^([^%s]+)%s+(%d+)")
- if string.find(devname, pd:get_device_name()) then
- swap = swap + tonumber(amount)
- end
- end
- line = pty:readline()
- end
- pty:close()
-
- return math.floor(swap / 1024)
- end
-
- -- Return an iterator which yields the next next
- -- PartitionDescriptor object in this DiskDescriptor
- -- each time it is called (typically in a for loop.)
- pd.get_subparts = function(pd)
- local letter, spd
- local list = {}
- local i, n = 0, 0
-
- for letter, spd in subpart do
- table.insert(list, spd)
- end
-
- table.sort(list, function(a, b)
- -- not sure why we ever get a nil here, but we do:
- if not a and not b then return false end
-
- return a:get_letter() < b:get_letter()
- end)
-
- n = table.getn(list)
-
- return function()
- if i <= n then
- i = i + 1
- return list[i]
- end
- end
- end
-
- pd.clear_subparts = function(pd)
- subpart = {}
- end
-
- pd.add_subpart = function(pd, spd)
- subpart[spd:get_letter()] = spd
- -- spd:set_parent(pd)
- end
-
- pd.get_subpart_by_letter = function(pd, letter)
- return subpart[letter]
- end
-
- pd.get_subpart_by_mountpoint = function(pd, mountpoint)
- local letter, spd
-
- for letter, spd in subpart do
- if spd:get_mountpoint() == mountpoint then
- return spd
- end
- end
-
- return nil
- end
-
- pd.get_subpart_by_device_name = function(pd, device_name)
- local letter, spd
-
- -- Strip any leading /dev/ or whatever.
- device_name = FileName.basename(device_name)
-
- for letter, spd in subpart do
- if spd:get_device_name() == device_name then
- return spd
- end
- end
-
- return nil
- end
-
- --
- -- Determine whether any subpartition of this
- -- partition is mounted somewhere in the filesystem.
- --
- pd.is_mounted = function(pd)
- local fs_descs = MountPoints.enumerate()
- local i, fs_desc, dev_name
-
- dev_name = pd:get_device_name()
- for i, fs_desc in fs_descs do
- if string.find(fs_desc.device, dev_name, 1, true) then
- return true
- end
- end
-
- return false
- end
-
- --
- -- Methods to add appropriate commands to CmdChains.
- --
-
- -- Commands to ensure this device exists.
- pd.cmds_ensure_dev = function(pd, cmds)
- cmds:add({
- cmdline = "cd ${root}dev && ${root}${TEST_DEV} ${dev} || " ..
- "${root}${SH} MAKEDEV ${dev}",
- replacements = {
- dev = FileName.basename(pd:get_device_name())
- }
- })
- end
-
- -- Commands to format this partition.
- pd.cmds_format = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
-
- -- The information in parent NEEDS to be accurate here!
- -- Presumably we just did a survey_storage() recently.
-
- --
- -- Set the slice's sysid to 165.
- --
-
- local cyl, head, sec = parent:get_geometry()
- local start, size, sysid, flags = pd:get_params()
-
- cmds:set_replacements{
- cyl = cyl,
- head = head,
- sec = sec,
- number = pd:get_number(),
- sysid = 165,
- start = start,
- size = size,
- dev = pd:get_raw_device_name(),
- parent_dev = parent:get_raw_device_name()
- }
-
- cmds:add(
- "${root}${ECHO} 'g c${cyl} h${head} s${sec}' >${tmp}new.fdisk",
- "${root}${ECHO} 'p ${number} ${sysid} ${start} ${size}' >>${tmp}new.fdisk"
- )
-
- if pd:is_active() then
- cmds:add("${root}${ECHO} 'a ${number}' >>${tmp}new.fdisk")
- end
-
- App.register_tmpfile("new.fdisk")
-
- --
- -- Dump the fdisk script to the log for debugging.
- -- Execute the fdisk script
- -- Auto-disklabel the slice.
- -- Remove any old disklabel that might be hanging around.
- --
- cmds:add(
- "${root}${CAT} ${tmp}new.fdisk",
- "${root}${FDISK} -v -f ${tmp}new.fdisk ${parent_dev}",
- "${root}${DISKLABEL} -B -r -w ${dev} auto",
- "${root}${RM} -f ${tmp}install.disklabel.${parent_dev}"
- )
- end
-
- pd.cmds_wipe_start = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
- cmds:add(
- "${root}${DD} if=${root}dev/zero of=${root}dev/" ..
- pd:get_raw_device_name() .. " bs=32k count=16"
- )
- end
-
- pd.cmds_install_bootstrap = function(pd, cmds)
- pd:cmds_ensure_dev(cmds)
- --
- -- NB: one cannot use "/dev/adXsY" here -
- -- it must be in the form "adXsY".
- --
- cmds:add(
- "${root}${DISKLABEL} -B " ..
- pd:get_raw_device_name()
- )
- return cmds
- end
-
- pd.cmds_disklabel = function(pd, cmds)
- -- Disklabel the given partition with the
- -- subpartitions attached to it.
-
- local num_parts = 8
- if App.os.name == "DragonFly" then
- num_parts = 16
- end
-
- cmds:set_replacements{
- part = pd:get_device_name(),
- num_parts = tostring(num_parts)
- }
-
- if not FileName.is_file(App.dir.tmp .. "install.disklabel" .. pd:get_device_name()) then
- --
- -- Get a copy of the 'virgin' disklabel.
- -- XXX It might make more sense for this to
- -- happen right after format_slice() instead.
- --
- cmds:add("${root}${DISKLABEL} -r ${part} >${tmp}install.disklabel.${part}")
- end
-
- --
- -- Weave together a new disklabel out the of the 'virgin'
- -- disklabel, and the user's subpartition choices.
- --
-
- --
- -- Take everything from the 'virgin' disklabel up until the
- -- '8 or 16 partitions' line, which looks like:
- --
- -- 8 or 16 partitions:
- -- # size offset fstype [fsize bsize bps/cpg]
- -- c: 2128833 0 unused 0 0 # (Cyl. 0 - 2111*)
- --
-
- cmds:add(
- "${root}${AWK} '$2==\"partitions:\" || cut { cut = 1 } !cut { print $0 }' " ..
- "<${tmp}install.disklabel.${part} >${tmp}install.disklabel",
- "${root}${ECHO} '${num_parts} partitions:' >>${tmp}install.disklabel",
- "${root}${ECHO} '# size offset fstype [fsize bsize bps/cpg]' " ..
- ">>${tmp}install.disklabel"
- )
-
- --
- -- Write a line for each subpartition the user wants.
- --
-
- local spd = nil
- local copied_original = false
-
- for spd in pd:get_subparts() do
- if spd:get_letter() > "c" and not copied_original then
- --
- -- Copy the 'c' line from the 'virgin' disklabel.
- --
- cmds:add("${root}${GREP} '^ c:' ${tmp}install.disklabel.${part} " ..
- ">>${tmp}install.disklabel")
- copied_original = true
- end
-
- cmds:set_replacements{
- letter = spd:get_letter(),
- fsize = spd:get_fsize(),
- bsize = spd:get_bsize()
- }
-
- if spd:get_letter() == "a" then
- cmds:set_replacements{ offset = "0" }
- else
- cmds:set_replacements{ offset = "*" }
- end
- if spd:get_size() == -1 then
- cmds:set_replacements{ size = "*" }
- else
- cmds:set_replacements{ size = tostring(spd:get_size()) }
- end
-
- if spd:is_swap() then
- cmds:add("${root}${ECHO} ' ${letter}:\t${size}\t*\tswap' >>${tmp}install.disklabel")
- else
- cmds:add("${root}${ECHO} ' ${letter}:\t${size}\t${offset}\t4.2BSD\t${fsize}\t${bsize}\t99' >>${tmp}install.disklabel")
- end
- end
-
- if not copied_original then
- --
- -- Copy the 'c' line from the 'virgin' disklabel,
- -- if we haven't yet (less than 2 subpartitions.)
- --
- cmds:add("${root}${GREP} '^ c:' ${tmp}install.disklabel.${part} >>${tmp}install.disklabel")
- end
-
- App.register_tmpfile("install.disklabel")
-
- --
- -- Label the slice from the disklabel we just wove together.
- --
- -- Then create a snapshot of the disklabel we just created
- -- for debugging inspection in the log.
- --
- cmds:add(
- "${root}${DISKLABEL} -R -B -r ${part} ${tmp}install.disklabel",
- "${root}${DISKLABEL} ${part}"
- )
-
- --
- -- Create filesystems on the newly-created subpartitions.
- --
- pd:get_parent():cmds_ensure_dev(cmds)
- pd:cmds_ensure_dev(cmds)
-
- for spd in pd:get_subparts() do
- if not spd:is_swap() then
- spd:cmds_ensure_dev(cmds)
-
- if spd:is_softupdated() then
- cmds:add("${root}${NEWFS} -U ${root}dev/" ..
- spd:get_device_name())
- else
- cmds:add("${root}${NEWFS} ${root}dev/" ..
- spd:get_device_name())
- end
- end
- end
- end
-
- pd.cmds_write_fstab = function(pd, cmds, filename)
- -- Write a new fstab for the given partition
- -- to the given filename.
-
- if not filename then
- filename = "${root}mnt/etc/fstab"
- end
-
- cmds:set_replacements{
- header = "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#",
- procline = "proc\t\t\t/proc\t\tprocfs\trw\t\t0\t0",
- device = "???",
- mountpoint = "???",
- filename = App.expand(filename)
- }
-
- cmds:add("${root}${ECHO} '${header}' >${filename}")
-
- for spd in pd:get_subparts() do
- cmds:set_replacements{
- device = spd:get_device_name(),
- mountpoint = spd:get_mountpoint()
- }
-
- if spd:get_mountpoint() == "/" then
- cmds:add("${root}${ECHO} '/dev/${device}\t\t${mountpoint}\t\tufs\trw\t\t1\t1' >>${filename}")
- elseif spd:is_swap() then
- cmds:add("${root}${ECHO} '/dev/${device}\t\tnone\t\tswap\tsw\t\t0\t0' >>${filename}")
- else
- cmds:add("${root}${ECHO} '/dev/${device}\t\t${mountpoint}\t\tufs\trw\t\t2\t2' >>${filename}")
- end
- end
-
- cmds:add("${root}${ECHO} '${procline}' >>${filename}")
- end
-
- pd.dump = function(pd)
- local letter, spd
-
- print("\t\tPartition " .. number .. ": " ..
- start .. "," .. size .. ":" .. sysid .. "/" .. flags)
- for spd in pd:get_subparts() do
- spd:dump()
- end
- end
-
- App.log("New Partition: " .. number .. ": " ..
- start .. "," .. size .. ":" .. sysid .. "/" .. flags)
-
- -- 'Constructor' - initialize this object's state.
- -- If this looks like a BSD slice, try to probe it with
- -- disklabel to get an idea of the subpartitions on it.
-
- local pty, line, found, len
- local letter, size, offset, fstype, fsize, bsize
-
- if sysid == 165 then
- pty = Pty.open(App.expand("${root}${DISKLABEL} " .. parent:get_name() ..
- "s" .. number))
- line = pty:readline()
- found = false
- while line and not found do
- found = string.find(line, "^%d+%s+partitions:")
- line = pty:readline()
- end
- if found then
- while line do
- found, len, letter, size, offset, fstype,
- fsize, bsize = string.find(line,
- "^%s*(%a):%s*(%d+)%s*(%d+)%s*([^%s]+)")
- if found then
- fsize, bsize = 0, 0
- if fstype == "4.2BSD" then
- found, len, letter, size,
- offset, fstype, fsize,
- bsize = string.find(line,
- "^%s*(%a):%s*(%d+)%s*" ..
- "(%d+)%s*([^%s]+)%s*" ..
- "(%d+)%s*(%d+)")
- end
- subpart[letter] =
- SubpartitionDescriptor.new{
- parent = pd,
- letter = letter,
- size = size,
- offset = offset,
- fstype = fstype,
- fsize = fsize,
- bsize = bsize
- }
- end
- line = pty:readline()
- end
- end
-
- pty:close()
- end
-
- return pd
-end
-
---[[------------------------]]--
---[[ SubpartitionDescriptor ]]--
---[[------------------------]]--
-
-SubpartitionDescriptor = {}
-SubpartitionDescriptor.new = function(params)
- local spd = {} -- instance variable
-
- local parent = assert(params.parent)
- local letter = assert(params.letter)
- local size = assert(params.size)
- local offset = assert(params.offset)
- local fstype = assert(params.fstype)
- local fsize = assert(params.fsize)
- local bsize = assert(params.bsize)
- local mountpoint = params.mountpoint
-
- -- Now set up this object's interface functions
-
- spd.get_parent = function(spd)
- return parent
- end
-
- spd.get_letter = function(spd)
- return letter
- end
-
- spd.set_mountpoint = function(spd, new_mountpoint)
-