installer(8): Auto fill default router in fn_assign_ip()
Add field change callbacks for "interface_ip" and "interface_netmask"
fields to auto fill/update the default router according to the IP and
netmask.
In addition, set the default netmask to "255.255.255.0".
Fix bug #3382
Bug: https://bugs.dragonflybsd.org/issues/3382
Reported-by: Nelson H. F. Beebe
installer(8): Fix hostname FQDN handling in fn_assign_ip()
Append domain to create FQDN only when the domain is not empty, similar
to the logic in fn_assign_hostname_domain().
installer(8): Avoid prompting for hostname and domain twice
During the manual IP configuration, the installer prompted for the
hostname and domain. Later, the main configuration menu prompted for
them again.
Retrieve the hostname and domain from rc_conf/resolv_conf variables, and
pre-populate the form fields to avoid the duplicate prompts.
In addition, pre-populate the DNS server field from resolv_conf vars.
Fix bug #3383.
Bug: https://bugs.dragonflybsd.org/issues/3383
Reported-by: Nelson H. F. Beebe
installer(8): Implement form field change callback mechanism
Implement a callback mechanism for form field change. This allows the
backend to dynamically update the dependent form fields when user
modifies one field.
The whole interaction flow is:
1. Set the callback function for a form field;
2. The frontend presents the form;
3. User fills the field and changes focus;
4. The frontend sends the FIELD_CHANGED message and waits for the reply;
5. The backend handles the message, triggers the callback, and replies
the FIELD_CHANGED_ACK message with the full dataset;
6. The frontend applies the dataset to present the updated form.
For example, when user fills the interface IP address, the callback will
auto fill the default router / gateway address.
TODO: The following low-priority features are missing:
[4 lines not shown]
installer(8): Refactor vars handling to avoid writing duplicates
config_vars_write() appends the in-memory vars to the target config
file. fn_assign_hostname_domain() fn_assign_ip() previously both read
the 'resolv.conf' and then write the updated vars, resulting duplicate
items being written to 'resolv.conf'.
Refactor the vars handling to start with empty 'rc_conf' and
'resolv_conf' vars, adjust the above configure functions to add/set
variables, and only write the config files once at the end.
installer(8): Improve config_vars_read() to support CONFIG_TYPE_RESOLV
The config_vars_read() function previously only supported CONFIG_TYPE_SH
and ignored CONFIG_TYPE_RESOLV that's supported by config_vars_write().
Add the CONFIG_TYPE_RESOLV file support to config_vars_read(). This
change is required in later commits that improve/simplify the
installation flow.
installer(8): Use pgrep(1) to check frontend/backend processes
Use 'pgrep -x' to correctly match the frontend/backend processes. This
is simpler than the original ps+grep method and fixes the partial match
problem. For example, the old grep would incorrectly match the tail(1)
process that was checking the `dfuibe_installer_debug.log` or
`dfuife_curses_debug.log` debug logs.
installer(8): Remove unused and unfinished fn_select_services()
This configuration function is intended for enable/disable services.
However, it's unfinished (doesn't update rc.conf) and unused (i.e.,
commented out in the form). Even if we could fix them, it still needs
to start/stop the changed services and to distinguish whether it's
configuring the LiveCD environment or the target installed system.
On the other hand, it's simple and effective to just edit rc.conf (after
booting into the newly installed system) to achieve the purpose. So
simply remove this function to clean up the installer mess a bit.
Discussed-with: swildner
installer(8): Auto fill default router in fn_assign_ip()
Add field change callbacks for "interface_ip" and "interface_netmask"
fields to auto fill/update the default router according to the IP and
netmask.
In addition, set the default netmask to "255.255.255.0".
Fix bug #3382
Bug: https://bugs.dragonflybsd.org/issues/3382
Reported-by: Nelson H. F. Beebe
installer(8): Implement form field change callback mechanism
Implement a callback mechanism for form field change. This allows the
backend to dynamically update the dependent form fields when user
modifies one field.
The whole interaction flow is:
1. Set the callback function for a form field;
2. The frontend presents the form;
3. User fills the field and changes focus;
4. The frontend sends the FIELD_CHANGED message and waits for the reply;
5. The backend handles the message, triggers the callback, and replies
the FIELD_CHANGED_ACK message with the full dataset;
6. The frontend applies the dataset to present the updated form.
For example, when user fills the interface IP address, the callback will
auto fill the default router / gateway address.
TODO: The following low-priority features are missing:
[4 lines not shown]
installer(8): Refactor vars handling to avoid writing duplicates
config_vars_write() appends the in-memory vars to the target config
file. fn_assign_hostname_domain() fn_assign_ip() previously both read
the 'resolv.conf' and then write the updated vars, resulting duplicate
items being written to 'resolv.conf'.
Refactor the vars handling to start with empty 'rc_conf' and
'resolv_conf' vars, adjust the above configure functions to add/set
variables, and only write the config files once at the end.
installer(8): Fix hostname FQDN handling in fn_assign_ip()
Append domain to create FQDN only when the domain is not empty, similar
to the logic in fn_assign_hostname_domain().
installer(8): Avoid prompting for hostname and domain twice
During the manual IP configuration, the installer prompted for the
hostname and domain. Later, the main configuration menu prompted for
them again.
Retrieve the hostname and domain from rc_conf/resolv_conf variables, and
pre-populate the form fields to avoid the duplicate prompts.
In addition, pre-populate the DNS server field from resolv_conf vars.
Fix bug #3383.
Bug: https://bugs.dragonflybsd.org/issues/3383
Reported-by: Nelson H. F. Beebe
installer(8): Improve config_vars_read() to support CONFIG_TYPE_RESOLV
The config_vars_read() function previously only supported CONFIG_TYPE_SH
and ignored CONFIG_TYPE_RESOLV that's supported by config_vars_write().
Add the CONFIG_TYPE_RESOLV file support to config_vars_read(). This
change is required in later commits that improve/simplify the
installation flow.
kernel/rman: Fix error return in sysctl_rman().
Matt changed the error handling in 869748ea0626d3966a0b0e1a8223de70ef05
but forgot to return 'error' from now on.
This fixes devinfo -r (show hardware resource information).
installer(8): Use pgrep(1) to check frontend/backend processes
Use 'pgrep -x' to correctly match the frontend/backend processes. This
is simpler than the original ps+grep method and fixes the partial match
problem. For example, the old grep would incorrectly match the tail(1)
process that was checking the `dfuibe_installer_debug.log` or
`dfuife_curses_debug.log` debug logs.
gpt(8): Improve "show" command to print a disk summary line
Before print the partition entries, print a disk summary line like:
"Disk /dev/da0: 50.0GB (104857600 512-byte sectors)".
In addition, add a blank line between disks.
Example new output:
```
$ sudo gpt show /dev/da0 ad0
Disk /dev/da0: 50.0GB (104857600 512-byte sectors)
start size index contents
0 1 - PMBR
1 1 - Pri GPT header
2 32 - Pri GPT table
34 2014 - Unused
2048 262144 0 GPT part - EFI System
264192 104591360 1 GPT part - DragonFly Label64
104855552 2015 - Unused
[14 lines not shown]
gpt(8): Print a warning message when gpt_write() fails
gpt_write() is used in many places and all of them don't handle the
writing failure, so update gpt_write() to print a warning message when
it fails.
gpt(8): Fix surrogate pair handling bug in utf16_to_utf8()
* The old code mishandled surrogate pairs and thus failed to recognize
valid UTF-16 characters and would replace them with 0xFFFD. Fix the
code to correctly handle the surrogate pairs.
* Fix an out-of-bound access in the old code when it tried to handle the
surrogate pairs. Check `s16idx < s16len` before accessing it with
`le16toh(s16[s16idx])`.
* Remove the `if (utfchar < 0x200000)` branch, because it's impossible
for `utfchar` exceeding 0x200000.
* Tweak the `while` loop conditional to clean up the code.
Credit: ChatGPT (https://chatgpt.com/)
gpt(8): Change utf8_to_utf16/utf16_to_utf8() to use 'char *'
Use 'char *' instead of 'uint8_t *' for NUL-terminated UTF-8 strings,
making it easier for callers.
gpt(8): Fix bugs in utf8_to_utf16()
- The 'utfchar' was incorrectly reinitialized to zero on every loop
iteration and thus destroyed the decoding state of multi-byte UTF-8
sequences. Fix it.
- Fix the endianness by adding the missing htole16() calls.
Obtained-from: NetBSD
gpt(8): Improve utf8_to_utf16()
- No need to NUL-terminate the UTF-16 string when it needs truncation.
- Pad the remaining characters with zeros. (obtained from NetBSD)
gpt(8): Improve utf16_to_utf8()
- Let caller pass the buffer and thus avoid memory allocation.
- Handle the case that there is no NUL termination, i.e., the partition
name is exactly 36 characters, which is allowed by the specification.
Obtained-from: NetBSD
gpt(8): Fix gpt_read() to report partial read error
A partial read() wouldn't touch 'errno', so the caller was unable to
know the error reason. This caused the program to print an error
message like:
```
gpt show: unable to open device 'vn4': Undefined error: 0
```
Fix gpt_read() to return E2BIG (I couldn't find a better choice) for a
partial read(), so the above error becomes:
```
gpt show: unable to open device 'vn4': Argument list too long
```
Still a bit weird, but better, I guess.
gpt(8): Clear errno before retrying open() in gpt_open()
Otherwise, the stale errno would go through gpt_read() when it failed
with a partial read, and the program would print a weird error message
like:
```
gpt show: unable to open device 'vn4': No such file or directory
```
Suggested-by: swildner