Date: Wed, 23 Nov 2005 06:18:28 GMT From: soc-andrew <soc-andrew@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87114 for review Message-ID: <200511230618.jAN6ISJV023288@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87114 Change 87114 by soc-andrew@soc-andrew_serv on 2005/11/23 06:18:18 Update the BSD Installer Affected files ... .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/install/220_format_disk.lua#3 edit .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/network.lua#4 edit .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/package.lua#4 edit .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/storage.lua#4 edit .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/target_system.lua#5 edit .. //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/target_system_ui.lua#3 edit Differences ... ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/install/220_format_disk.lua#3 (text+ko) ==== @@ -1,12 +1,113 @@ --- $Id: 220_format_disk.lua,v 1.13 2005/10/05 21:29:03 cpressey Exp $ +-- $Id: 220_format_disk.lua,v 1.14 2005/10/12 00:50:12 cpressey Exp $ -- -- Allow the user to format the selected disk, if they so desire. -- +-- +-- Utility function which asks the user what geometry they'd like to use. +-- +local select_geometry = function(step, dd) + local c_cyl, c_head, c_sec = dd:get_geometry() + local geom_msg = _( + "The system is reports that the geometry of %s is\n\n" .. + "%d cylinders, %d heads, %d sectors\n\n", + dd:get_name(), + dd:get_geometry_cyl(), + dd:get_geometry_head(), + dd:get_geometry_sec() + ) + local valid_msg + if dd:is_geometry_bios_friendly() then + valid_msg = _( + "This geometry should enable you to boot from " .. + "this disk. Unless you have a pressing reason " .. + "to do otherwise, it is recommended that you use " .. + "it.\n\n" + ) + else + c_cyl, c_head, c_sec = dd:get_normalized_geometry() + valid_msg = _( + "This geometry will NOT enable you to boot from " .. + "this disk! Unless you have a pressing reason " .. + "to do otherwise, it is recommended that you use " .. + "the following modified geometry:\n\n" .. + "%d cylinders, %d heads, %d sectors\n\n", + c_cyl, c_head, c_sec + ) + end + local end_msg = _( + "If you don't understand what any of this means, just " .. + "select 'Use this Geometry' to continue." + ) + + local response = App.ui:present{ + id = "select_geometry", + name = _("Select Geometry"), + short_desc = geom_msg .. valid_msg .. end_msg, + + fields = { + { + id = "cyl", + name = _("Cylinders"), + short_desc = _("Enter the number of cylinders in this disk's geometry") + }, + { + id = "head", + name = _("Heads"), + short_desc = _("Enter the number of heads in this disk's geometry") + }, + { + id = "sec", + name = _("Sectors"), + short_desc = _("Enter the number of sectors in this disk's geometry") + }, + }, + + datasets = { + { + cyl = tostring(c_cyl), + head = tostring(c_head), + sec = tonumber(c_sec) + } + }, + + actions = { + { + id = "ok", + name = _("Use this Geometry") + }, + { + id = "cancel", + accelerator = "ESC", + name = _("Return to %s", step:get_prev_name()) + } + } + } + + if response.action_id == "ok" then + dd:set_geometry( + tonumber(response.datasets[1].cyl), + tonumber(response.datasets[1].head), + tonumber(response.datasets[1].sec) + ) + return true + else + return false + end +end + +-- +-- Utility function which confirms that the user would like to proceed, +-- and actually executes the formatting commands. +-- local format_disk = function(step, dd) local cmds = CmdChain.new() + if not select_geometry(step, dd) then + return false + end + dd:cmds_format(cmds) local confirm = function() ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/network.lua#4 (text+ko) ==== @@ -1,4 +1,4 @@ --- $Id: network.lua,v 1.21 2005/09/02 22:07:53 cpressey Exp $ +-- $Id: network.lua,v 1.22 2005/11/10 16:38:02 cpressey Exp $ -- Lua abstraction for the Network Interfaces of a system. -- ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/package.lua#4 (text+ko) ==== @@ -93,7 +93,7 @@ -- method.is_archived_on = function(ps, ts) local filename = App.expand( - "${root}${base}usr/ports/packages/All/${name}.${suffix}", + "${root}${base}usr/packages/All/${name}.${suffix}", { base = ts:get_base(), name = name, @@ -119,7 +119,7 @@ if self:is_archived_on(ts) then cmd = App.expand( "${root}${TAR} -O -z -x -f " .. - "${root}usr/ports/packages/All/${pkg_name}.${suffix} " .. + "${root}usr/packages/All/${pkg_name}.${suffix} " .. "+CONTENTS | ${root}${GREP} '^@pkgdep'", { base = ts:get_base(), pkg_name = self:get_name(), @@ -253,7 +253,7 @@ -- if self:is_archived_on(App.state.source) then cmds:add( - "${root}${CP} ${root}usr/ports/packages/All/${pkg_name}.${pkg_suffix} " .. + "${root}${CP} ${root}usr/packages/All/${pkg_name}.${pkg_suffix} " .. "${root}${base}${pkg_tmp}/${pkg_name}.${pkg_suffix}" ) else @@ -485,7 +485,7 @@ -- method.enumerate_archived_on = function(self, ts) self:enumerate_archives_in( - App.expand("${root}${base}usr/ports/packages/All", { + App.expand("${root}${base}usr/packages/All", { base = ts:get_base() }) ) ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/storage.lua#4 (text+ko) ==== @@ -1,4 +1,4 @@ --- $Id: storage.lua,v 1.177 2005/10/05 20:27:40 cpressey Exp $ +-- $Id: storage.lua,v 1.182 2005/10/28 02:48:02 cpressey Exp $ -- Storage Descriptors (a la libinstaller) in Lua. -- @@ -685,6 +685,46 @@ return sec end + method.set_geometry = function(self, c, h, s) + cyl = c or cyl + head = h or head + sec = s or sec + end + + -- + -- Determine whether the geometry of the disk is "BIOS friendly" + -- or not, i.e., whether the C/H/S parameters are within the + -- limits of what is supported by legacy means of reading the + -- disk (int 13h), which are required during e.g. booting. + -- + -- This is needed because sometimes the system reports a + -- geometry for an unformatted disk as having some number of + -- sectors per track, such as 255, that will not permit booting + -- from the BIOS. + -- + -- XXX It is also possible that some systems require the number + -- of heads to be 16 or less, especially if they are set to + -- use "LBA" geometry translation. + -- + method.is_geometry_bios_friendly = function(self) + return sec >= 1 and sec <= 63 + end + + -- + -- Find a "BIOS-friendly" geometry that corresponds to the + -- capacity of this disk, so we can at least boot from it. + -- + method.get_normalized_geometry = function(self) + -- + -- Convert to something that the BIOS can boot from. + -- + local sec = 63 + local head = 255 + local cyl = math.floor(capacity:in_units("S") / (sec * head)) + + return cyl, head, sec + end + -- -- Return the name of the device which handles this disk. -- Note that, on all currently supported operating systems, @@ -907,28 +947,89 @@ end -- - -- Create commands to format (create one big partition on) this disk. + -- Create commands to format this disk. 'Format' in this sense + -- means to create one big partition, and to install a partition + -- table with the appropriate information in it. -- method.cmds_format = function(self, cmds) self:cmds_ensure_dev(cmds) -- - -- Currently you need to pass 'yes' to OpenBSD's fdisk to - -- be able to do these. (XXX this is a shot in the dark) + -- Initialize the disk. + -- + cmds:add("${root}${FDISK} -I " .. + self:get_raw_device_name()) + + -- + -- Under more pleasant conditions, we could just + -- shell 'fdisk -BI' here and be done with it. + -- However, life is not that simple. In order to + -- get fdisk to honour the geometry we have + -- selected, we need to create a fdisk script which + -- tells fdisk exactly the geometry of the disk and + -- the size of the partition we'd like to make. + -- + cmds:add{ + cmdline = "${root}${ECHO} 'g c${cyl} h${head} s${sec}' >${tmp}format.fdisk", + replacements = { + cyl = cyl, + head = head, + sec = sec + } + } + + -- + -- Allot the first partition as taking up the entire disk, + -- assuming the given geometry. This means that the part: + -- * has the default sysid (depends on the operating system); + -- * starts at the first track (after the zero'th track,) + -- * extends to the end of the disk. + -- + cmds:add{ + cmdline = "${root}${ECHO} 'p 1 ${sysid} ${start} ${size}' >>${tmp}format.fdisk", + replacements = { + sysid = App.conf.default_sysid, + start = sec, + size = (cyl * head * sec) - sec + } + } + + -- + -- Mark the other partitions as unused. + -- Mark the first partition as the active one. + -- Send a copy of this script to the log, and make sure + -- the system knows that it should delete it when done. + -- + cmds:add( + "${root}${ECHO} 'p 2 0 0 0' >>${tmp}format.fdisk", + "${root}${ECHO} 'p 3 0 0 0' >>${tmp}format.fdisk", + "${root}${ECHO} 'p 4 0 0 0' >>${tmp}format.fdisk", + "${root}${ECHO} 'a 1' >>${tmp}format.fdisk", + "${root}${CAT} ${tmp}format.fdisk" + ) + App.register_tmpfile("format.fdisk") + + -- + -- Execute the fdisk script. -- - if App.conf.os.name == "OpenBSD" then -- XXXXXX - cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " .. - "${root}${FDISK} -I " .. - self:get_raw_device_name()) - cmds:add("${root}${ECHO} 'yes\nyes\nyes\n' | " .. - "${root}${FDISK} -B " .. - self:get_raw_device_name()) + if App.conf.os.name == "NetBSD" then -- XXXXXX + -- XXX Going to need to do this differently else - cmds:add("${root}${FDISK} -I " .. - self:get_raw_device_name()) - cmds:add("${root}${YES} | ${root}${FDISK} -B " .. - self:get_raw_device_name()) + cmds:add("${root}${FDISK} -v -f ${tmp}format.fdisk " .. + self:get_device_name()) end + + -- + -- Show the new state of the disk in the log. + -- + cmds:add("${root}${FDISK} " .. + self:get_device_name()) + + -- + -- Make the disk bootable. + -- + cmds:add("${root}${YES} | ${root}${FDISK} -B " .. + self:get_raw_device_name()) end -- @@ -1107,20 +1208,28 @@ end -- - -- Probe the (BIOS) geometry and the capacity of the disk. - -- Returns true, then the geometry (C, H, S,) then the capacity, - -- if all went well. Returns nil and an error message if not. + -- Probe the (BIOS) geometry of the disk. + -- Returns three values: cylinder, head, and sec/trk, if all went well. + -- Returns nil values if all did not go well. + -- Capacity in sectors can then be calculated by C * H * S, or an error + -- can be flagged, by the caller of this function. + -- -- This is the FreeBSD/DragonFly version of this function. -- local probe_geometry_freebsd = function(self) - local cyl, head, sec, capacity + local cyl, head, sec -- - -- Tell 'fdisk' to pretend to initialize the disk and - -- parse its output, to determine total # of sectors. + -- Tell 'fdisk' to give us the rundown of the disk. + -- Note that this does not use the 'summary' (-s) + -- feature of fdisk, because that feature has markedly + -- different behaviour when the disk is blank or + -- otherwise has an invalid boot sector: it fails + -- immediately. Whereas we need it to provide at least + -- the geometry (even if the part table is ficticious.) -- local cmd = App.expand( - "${root}${FDISK} -t -I " .. self:get_raw_device_name() + "${root}${FDISK} " .. self:get_raw_device_name() ) local pty = Pty.Logged.open(cmd, App.log_string) if not pty then @@ -1128,53 +1237,43 @@ end local line = pty:readline() while line do - local found_size, len, start, size = - string.find(line, "start%s*(%d+)%s*,%s*size%s*(%d+)") - if found_size then - capacity = Storage.Capacity.new( - tonumber(start) + tonumber(size), "S" - ) - end - local found_bios_geom = - string.find(line, "^%s*parameters to be used for BIOS") - line = pty:readline() - if found_bios_geom then + if string.find(line, "^%s*parameters to be used for BIOS") then -- -- Parse the line following. -- + line = pty:readline() 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) - found_bios_geom = false + if found then + cyl = tonumber(cyl) + head = tonumber(head) + sec = tonumber(sec) + end + line = pty:readline() + else + -- + -- Keep looking... + -- line = pty:readline() end end pty:close() - if not cyl or not head or not sec then - return nil, string.format( - "could not determine geometry of disk '%s'", name - ) - end - if not capacity then - return nil, string.format( - "could not determine capacity of disk '%s'", name - ) - end - return true, cyl, head, sec, capacity + return cyl, head, sec end -- - -- Probe the (BIOS) geometry and the capacity of the disk. - -- Returns true, then the geometry (C, H, S,) then the capacity, - -- if all went well. Returns nil and an error message if not. + -- Probe the (BIOS) geometry of the disk. + -- Returns three values: cylinder, head, and sec/trk, if all went well. + -- Returns nil values if all did not go well. + -- Capacity in sectors can then be calculated by C * H * S, or an error + -- can be flagged, by the caller of this function. + -- -- This is the NetBSD version of this function. -- local probe_geometry_netbsd = function(self) - local cyl, head, sec, capacity + local cyl, head, sec -- -- Call 'fdisk' and parse its output. @@ -1188,13 +1287,6 @@ end local line = pty:readline() while line do - local found_size, len, size = - string.find(line, "^%s*total%s*sectors:%s*(%d+)") - if found_size then - capacity = Storage.Capacity.new( - tonumber(size), "S" - ) - end local found_bios_geom = string.find(line, "^%s*NetBSD%s*disklabel%s*disk%s*geometry") line = pty:readline() @@ -1214,17 +1306,7 @@ end pty:close() - if not cyl or not head or not sec then - return nil, string.format( - "could not determine geometry of disk '%s'", name - ) - end - if not capacity then - return nil, string.format( - "could not determine capacity of disk '%s'", name - ) - end - return true, cyl, head, sec, capacity + return cyl, head, sec end local probe_partitions_freebsd = function(self) @@ -1381,18 +1463,25 @@ local success if App.conf.os.name == "NetBSD" then -- XXXXXX netbsd needs its own subclass here - success, cyl, head, sec, capacity = + cyl, head, sec = probe_geometry_netbsd(self) else - success, cyl, head, sec, capacity = + cyl, head, sec = probe_geometry_freebsd(self) end - if not success then - App.log_warn(cyl) -- 'cyl' is the error message + if not cyl or not head or not sec then + App.log_warn( + "could not determine geometry of disk '%s'", name + ) return false end + -- + -- Calculate disk's capacity from its geometry. + -- + capacity = Storage.Capacity.new(cyl * head * sec, "S") + App.log("Disk " .. name .. " (" .. desc .. "): " .. capacity:format() .. ": " .. cyl .. "/" .. head .. "/" .. sec) ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/target_system.lua#5 (text+ko) ==== @@ -413,9 +413,9 @@ dir = src end cmds:add{ - cmdline = "${root}${TAR} " .. - "-x -C ${root}${base}${dest} -f " .. - "${root}usr/${uname}/${dir}/${src}.${dist_suffix}", + cmdline = "${root}${TAR} -f " .. + "${root}usr/${uname}/${dir}/${src}.${dist_suffix}" .. + "-x -C ${root}${base}${dest}" replacements = { base = base, src = src, ==== //depot/projects/soc2005/bsdinstaller/src/contrib/bsdinstaller/backend/lua/lib/target_system_ui.lua#3 (text+ko) ==== @@ -1,4 +1,4 @@ --- $Id: target_system_ui.lua,v 1.15 2005/08/26 04:25:25 cpressey Exp $ +-- $Id: target_system_ui.lua,v 1.16 2005/10/12 00:43:51 cpressey Exp $ -- -- Copyright (c)2005 Chris Pressey. All rights reserved. @@ -49,579 +49,579 @@ end TargetSystemUI.set_root_password = function(ts) - 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", - accelerator = "ESC", - name = _("Return to Configure Menu") - } - }, - - datasets = { - { root_passwd_1 = "", root_passwd_2 = "" } - } + 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", + accelerator = "ESC", + name = _("Return to Configure Menu") } - - while not done do - result = ui:present(form) - - if result.action_id == "ok" then - form.datasets = result.datasets + }, + + datasets = { + { root_passwd_1 = "", root_passwd_2 = "" } + } + } + + while not done do + result = 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 + -- XXX validate password for bad characters here XXX + + if root_passwd_1 == root_passwd_2 then -- - -- Fetch form field values. + -- Passwords match, so set the root password. -- - - local root_passwd_1 = result.datasets[1].root_passwd_1 - local root_passwd_2 = result.datasets[1].root_passwd_2 - - -- XXX validate password for bad characters here XXX - - if root_passwd_1 == root_passwd_2 then - -- - -- Passwords match, so set the root password. - -- - cmds = CmdChain.new() - ts:cmds_set_password(cmds, - "root", root_passwd_1) - if cmds:execute() then - ui:inform( - _("The root password has been changed.") - ) - done = true - else - ui:inform( - _("An error occurred when " .. - "setting the root password.") - ) - done = false - end + cmds = CmdChain.new() + ts:cmds_set_password(cmds, + "root", root_passwd_1) + if cmds:execute() then + ui:inform( + _("The root password has been changed.") + ) + done = true else - -- - -- Passwords don't match - tell the user, let them try again. - -- ui:inform( - _("The passwords do not match.") + _("An error occurred when " .. + "setting the root password.") ) done = false end else - -- Cancelled - done = true + -- + -- Passwords don't match - tell the user, let them try again. + -- + ui:inform( + _("The passwords do not match.") + ) + done = false end + else + -- Cancelled + done = true end + end end TargetSystemUI.add_user = function(ts) - local done = false - local result - local cmds + local done = false + local result + local cmds - -- - -- Predicates which validate entered data. - -- - local is_gecos_clean = function(gecos) - local i, char + -- + -- Predicates which validate entered data. + -- + 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 + 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 + return true + end - local is_name_clean = function(name) - local i, char + 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 + 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 + return true + end - local is_filename_clean = function(filename) -- XXX incomplete - return true - end + local is_filename_clean = function(filename) -- XXX incomplete + return true + end - local is_uid_clean = function(uid) -- XXX incomplete - return true - end + local is_uid_clean = function(uid) -- XXX incomplete + return true + end - local is_grouplist_clean = function(grouplist) -- XXX incomplete - return true - end + local is_grouplist_clean = function(grouplist) -- XXX incomplete + return true + end - -- - -- Description of the form to display. - -- - 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", - accelerator = "ESC", - name = _("Return to Configure Menu") - } - }, - datasets = { - { - username = "", - gecos = "", - passwd_1 = "", - passwd_2 = "", - shell = "/bin/tcsh", - home = "", - uid = "", - group = "", - groups = "" - } - } + -- + -- Description of the form to display. + -- + 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", + accelerator = "ESC", + name = _("Return to Configure Menu") + } + }, + datasets = { + { + username = "", + gecos = "", + passwd_1 = "", + passwd_2 = "", + shell = "/bin/tcsh", + home = "", + uid = "", + group = "", + groups = "" } + } + } + + -- + -- Main loop which repeatedly displays the form until either + -- the user cancels or everything validates. + -- + while not done do + result = ui:present(form) + if result.action_id == "ok" then + form.datasets = result.datasets >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511230618.jAN6ISJV023288>