From: Florian Obser Subject: Re: installer: Default IPv6 router: use ask() to support ! and more To: tech@openbsd.org Date: Sat, 01 Feb 2025 19:32:37 +0100 I like what this does. I'm not a shell hacker so I don't feel comfortable reviewing or giving an OK. That being said, if nobody steps up I think you should just jam this in... On 2025-02-01 18:21 UTC, Klemens Nanni wrote: > The interactive version of this question is backed by ksh(1)'s select > instead of the intaller's ask*() routines, meaning > > - available routers are printed before the answer (or on empty input) > without explanation > - none is explicitly listed > - the answer is not recorded in the response file > - ! does not drop into a shell > - ? is not supported > > Network interface to configure? (name, lladdr, '?', or 'done') [done] > 1) none > 2) fe80::fce1:baff:fed0:9371%vio0 > IPv6 default router? (list #, IPv6 address or 'none') ! > route: !: non-recoverable failure in name resolution > route: !: non-recoverable failure in name resolution > IPv6 default router? (list #, IPv6 address or 'none') ? > route: ?: non-recoverable failure in name resolution > route: ?: non-recoverable failure in name resolution > IPv6 default router? (list #, IPv6 address or 'none') 0 > route: 0: no address associated with name > route: 0: no address associated with name > IPv6 default router? (list #, IPv6 address or 'none') foo > route: foo: no address associated with name > route: foo: no address associated with name > > I had to do route(8)'s last EXAMPLE when this forced me to abort > the install to run commands earlier... > > > Let's switch the only select usage to ask_until(), making it very > similar to how 'Default IPv4 route?' and 'Access Point?' are done: > > IPv6 default router? (IPv6 address, list#, 'none' or '?') ! > Type 'exit' to return to install. > test# ^D > IPv6 default router? (IPv6 address, list#, 'none' or '?') ? > 1 fe80::fce1:baff:fed0:9371%vio0 > IPv6 default router? (IPv6 address, list#, 'none' or '?') 0 > 0 is not a valid choice. > IPv6 default router? (IPv6 address, list#, 'none' or '?') foo > route: foo: no address associated with name > route: foo: no address associated with name > > > (A)utoinstall(8) is uneffected. The interactive/unattended paths could be > merged, but not without more churn, so here's the first step. > > Feedback? OK? > > This code runs so early, that you can even test it locally without disk > or real network; once a router is picked, the rest is the same: > > # vmctl start -c -i1 -b./bsd.rd foo > ... > IPv6 address for vio0? (or 'autoconf' or 'none') [none] 2001:db8::1/64 > Available network interfaces are: vio0 vlan0. > Network interface to configure? (name, lladdr, '?', or 'done') [done] > IPv6 default router? (IPv6 address, list#, 'none' or '?') 2001:db8::2 > add net default: gateway 2001:db8::2 > > Index: install.sub > =================================================================== > RCS file: /cvs/src/distrib/miniroot/install.sub,v > diff -u -p -r1.1266 install.sub > --- install.sub 9 Jul 2024 14:47:21 -0000 1.1266 > +++ install.sub 1 Feb 2025 16:44:42 -0000 > @@ -1146,7 +1146,7 @@ v6_info() { > # in the /etc/mygate file. Ask the user to either select from a list of default > # router candidates or to enter a router IPv6 address. > v6_defroute() { > - local _if _v6ifs _prompt _resp _routers _dr PS3 > + local _if _v6ifs _prompt _resp _routers _dr > > # Only configure a default route if an IPv6 address was manually configured. > for _if in $(get_ifs); do > @@ -1179,14 +1179,30 @@ v6_defroute() { > route -n add -inet6 -host default $resp && > echo $resp >>/tmp/i/mygate > else > - PS3="$_prompt (list #, IPv6 address or 'none') " > - select _resp in none $_routers; do > - [[ $REPLY == none || $_resp == none ]] && break > - [[ -z $_resp ]] && _resp=$REPLY > + set -A _routers -- $_routers > + while :; do > + ask_until "$_prompt (IPv6 address, list#, 'none' or '?')" > + case $resp in > + none) return > + ;; > + '?') for _dr in ${_routers[@]}; do > + echo $_dr > + done | cat -n > + continue > + ;; > + +([0-9])) > + if ((resp < 1 || resp > ${#_routers[@]})); then > + echo "$resp is not a valid choice." > + continue > + fi > + resp=${_routers[$((--resp))]} > + ;; > + esac > + > # Avoid possible "file exists" errors > - route -n -q delete -inet6 -host default $_resp > - if route -n add -inet6 -host default $_resp; then > - echo $_resp >>/tmp/i/mygate > + route -n -q delete -inet6 -host default "$resp" > + if route -n add -inet6 -host default "$resp"; then > + echo "$resp" >>/tmp/i/mygate > break > fi > done > -- In my defence, I have been left unsupervised.