Fix exit issue from main menu

This commit is contained in:
natemaia 2020-04-26 08:36:33 -07:00
parent e79981bdbe
commit 43e1cff680

View File

@ -7,7 +7,7 @@
# shellcheck disable=SC2086,SC2046,SC2254 # shellcheck disable=SC2086,SC2046,SC2254
VER=2.1.37 VER=2.1.38
# default values { # default values {
@ -318,7 +318,7 @@ _format="is already formatted correctly.\n\nFor a clean install, existing partit
_swapsize="\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\neg. 100M will create a 100 megabyte swapfile, while 10G will create a 10 gigabyte swapfile.\n\nFor ease of use and as an example it is filled in to match the size of your system memory (RAM).\n\nMust be greater than 1, contain only whole numbers, and end with either M or G." _swapsize="\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\neg. 100M will create a 100 megabyte swapfile, while 10G will create a 10 gigabyte swapfile.\n\nFor ease of use and as an example it is filled in to match the size of your system memory (RAM).\n\nMust be greater than 1, contain only whole numbers, and end with either M or G."
_expart="\nYou can now choose any additional partitions you want mounted, you'll be asked for a mountpoint after.\n\nSelect 'done' to finish the mounting step and begin unpacking the base system in the background." _expart="\nYou can now choose any additional partitions you want mounted, you'll be asked for a mountpoint after.\n\nSelect 'done' to finish the mounting step and begin unpacking the base system in the background."
_exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc." _exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc."
_bginstall="\nA background install portion will now begin, select what kind of base install to use\n\npacstrap - guarantees the latest packages and avoids conflicts but is much slower and network dependant\n\ncopy iso - much faster and not network dependant but can have issues\n" _bginstall="\nThe background install will now start, select which base install method to use\n\nPacstrap - guarantees the latest packages and avoids issues but is slower and network dependant\nCopy ISO - is faster and not network dependant but can result in installation issues\n"
_user="\nEnter a name and password for the new user account.\n\nThe name must not use capital letters, contain any periods (.), end with a hyphen (-), or include any colons (:)\n\nNOTE: Use [Up], [Down], or [Tab] to switch between fields, and [Enter] to accept." _user="\nEnter a name and password for the new user account.\n\nThe name must not use capital letters, contain any periods (.), end with a hyphen (-), or include any colons (:)\n\nNOTE: Use [Up], [Down], or [Tab] to switch between fields, and [Enter] to accept."
_hostname="\nEnter a hostname for the new system.\n\nA hostname is used to identify systems on the network.\n\nIt's restricted to alphanumeric characters (a-z, A-Z, 0-9).\nIt can contain hyphens (-) BUT NOT at the beginning or end." _hostname="\nEnter a hostname for the new system.\n\nA hostname is used to identify systems on the network.\n\nIt's restricted to alphanumeric characters (a-z, A-Z, 0-9).\nIt can contain hyphens (-) BUT NOT at the beginning or end."
_locale="\nLocale determines the system language and currency formats.\n\nThe format for locale names is languagecode_COUNTRYCODE\n\neg. en_US is: English United States\n en_GB is: English Great Britain" _locale="\nLocale determines the system language and currency formats.\n\nThe format for locale names is languagecode_COUNTRYCODE\n\neg. en_US is: English United States\n en_GB is: English Great Britain"
@ -369,7 +369,9 @@ _lvmerrlvsize="\nInvalid value Entered.\n\nMust be a numeric value with 'M' (meg
main() main()
{ {
# increment SEL every time we enter main() if we're not at the end of the menu
(( SEL < 13 )) && (( SEL++ )) (( SEL < 13 )) && (( SEL++ ))
tput civis tput civis
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " \ dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " \
--default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \ --default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \
@ -387,23 +389,26 @@ main()
12 "View configuration and command selections" \ 12 "View configuration and command selections" \
13 "* Confirm choices and start the installation" 2> "$ANS" 13 "* Confirm choices and start the installation" 2> "$ANS"
[[ -s "$ANS" ]] && read -r SEL < "$ANS" read -r SEL < "$ANS"
[[ -z $WARN && $SEL =~ (2|5) ]] && { msg "Data Warning" "$_warn"; WARN=true; } [[ -z $WARN && $SEL =~ (2|5) ]] && { msg "Data Warning" "$_warn"; WARN=true; }
# if the operation returns an error we decrement SEL, prechecks() will
# also set SEL to even further back based on what is needed to continue
case $SEL in case $SEL in
1) part_show ;; 1) part_show ;;
2) part_menu || (( SEL-- )) ;; 2) part_menu || (( SEL-- )) ;;
3) luks_menu || (( SEL-- )) ;; 3) luks_menu || (( SEL-- )) ;;
4) lvm_menu || (( SEL-- )) ;; 4) lvm_menu || (( SEL-- )) ;;
5) mount_menu || (( SEL-- )) ;; 5) mount_menu || (( SEL-- )) ;;
6) prechecks 0 && { select_bootldr || (( SEL-- )); } ;; 6) prechecks 0 && { select_bootldr || (( SEL-- )); } ;;
7) prechecks 1 && { select_mkuser || (( SEL-- )); } ;; 7) prechecks 1 && { select_mkuser || (( SEL-- )); } ;;
8) prechecks 2 && { select_config || (( SEL-- )); } ;; 8) prechecks 2 && { select_config || (( SEL-- )); } ;;
9) prechecks 3 && { select_sessions || (( SEL-- )); } ;; 9) prechecks 3 && { select_sessions || (( SEL-- )); } ;;
10) prechecks 3 && { select_packages || (( SEL-- )); } ;; 10) prechecks 3 && { select_packages || (( SEL-- )); } ;;
11) prechecks 3 && select_usercmd ;; 11) prechecks 3 && select_usercmd ;;
12) prechecks 3 && select_show ;; 12) prechecks 3 && select_show ;;
13) prechecks 3 && install_main ;; 13) prechecks 3 && install_main ;;
*) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0 *) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0
esac esac
} }
@ -499,8 +504,22 @@ select_config()
2) dlg LOCALE menu "Locale" "$_locale" $LOCALES || { i=1; continue; } ;; 2) dlg LOCALE menu "Locale" "$_locale" $LOCALES || { i=1; continue; } ;;
3) ZONE='' SUBZ='' 3) ZONE='' SUBZ=''
until [[ $ZONE && $SUBZ ]]; do until [[ $ZONE && $SUBZ ]]; do
dlg ZONE menu "Timezone" "$_timez" America - Australia - Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica - || break dlg ZONE menu "Timezone" "$_timez" \
dlg SUBZ menu "Timezone" "$_timesubz" $(awk '/'"$ZONE"'\// {gsub(/'"$ZONE"'\//, ""); print $3 " - "}' /usr/share/zoneinfo/zone.tab | sort) || continue America - \
Australia - \
Asia - \
Atlantic - \
Africa - \
Europe - \
Indian - \
Pacific - \
Arctic - \
Antarctica - || break
dlg SUBZ menu "Timezone" "$_timesubz" $(awk '/'"$ZONE"'\// {
gsub(/'"$ZONE"'\//, "")
print $3 " - "
}' /usr/share/zoneinfo/zone.tab | sort) || continue
done done
[[ $ZONE && $SUBZ ]] || { i=2; continue; } ;; [[ $ZONE && $SUBZ ]] || { i=2; continue; } ;;
4) dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \ 4) dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \
@ -527,16 +546,18 @@ select_mkuser()
{ {
NEWUSER='' NEWUSER=''
typeset -a ans typeset -a ans
local rootsec="--- Root password, if left empty the user password will be used ---"
until [[ $NEWUSER ]]; do until [[ $NEWUSER ]]; do
tput cnorm tput cnorm
dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " User " --mixedform "$_user" 0 0 0 \ dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" \
"Username:" 1 1 "${ans[0]}" 1 11 "$COLUMNS" 0 0 \ --separator $'\n' --title " User " --mixedform "$_user" 0 0 0 \
"Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \ "Username:" 1 1 "${ans[0]}" 1 11 "$COLUMNS" 0 0 \
"Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 \ "Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \
"--- Root password, if left empty the user password will be used ---" 6 1 '' 6 68 "$COLUMNS" 0 2 \ "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 \
"Password:" 8 1 '' 8 11 "$COLUMNS" 0 1 \ "$rootsec" 6 1 '' 6 68 "$COLUMNS" 0 2 \
"Password2:" 9 1 '' 9 12 "$COLUMNS" 0 1 2> "$ANS" || return 1 "Password:" 8 1 '' 8 11 "$COLUMNS" 0 1 \
"Password2:" 9 1 '' 9 12 "$COLUMNS" 0 1 2> "$ANS" || return 1
mapfile -t ans <"$ANS" mapfile -t ans <"$ANS"
@ -628,20 +649,21 @@ select_sessions()
{ {
LOGIN_CHOICES='' LOGIN_CHOICES=''
dlg INSTALL_WMS check "Sessions" "$_sessions\n" \ dlg INSTALL_WMS check "Sessions" "$_sessions\n" \
i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "${INSTALL_WMS[*]}")" \ i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "$INSTALL_WMS")" \
openbox "A lightweight, powerful, and highly configurable stacking wm" "$(ofn openbox "${INSTALL_WMS[*]}")" \ openbox "A lightweight, powerful, and highly configurable stacking wm" "$(ofn openbox "$INSTALL_WMS")" \
dwm "A dynamic WM for X that manages windows in tiled, floating, or monocle layouts" "$(ofn dwm "${INSTALL_WMS[*]}")" \ dwm "A dynamic WM for X that manages windows in tiled, floating, or monocle layouts" "$(ofn dwm "$INSTALL_WMS")" \
bspwm "A tiling wm that represents windows as the leaves of a binary tree" "$(ofn bspwm "${INSTALL_WMS[*]}")" \ bspwm "A tiling wm that represents windows as the leaves of a binary tree" "$(ofn bspwm "$INSTALL_WMS")" \
jwm "A lightweight window manager for Xorg written in C" "$(ofn jwm "${INSTALL_WMS[*]}")" \ jwm "A lightweight window manager for Xorg written in C" "$(ofn jwm "$INSTALL_WMS")" \
xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "${INSTALL_WMS[*]}")" \ xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "$INSTALL_WMS")" \
awesome "A customized Awesome WM session created by @elanapan" "$(ofn awesome "${INSTALL_WMS[*]}")" \ awesome "A customized Awesome WM session created by @elanapan" "$(ofn awesome "$INSTALL_WMS")" \
fluxbox "A lightweight and highly-configurable window manager" "$(ofn fluxbox "${INSTALL_WMS[*]}")" \ fluxbox "A lightweight and highly-configurable window manager" "$(ofn fluxbox "$INSTALL_WMS")" \
plasma "A KDE software project currently comprising a full desktop environment" "$(ofn plasma "${INSTALL_WMS[*]}")" \ plasma "A KDE software project currently comprising a full desktop environment" "$(ofn plasma "$INSTALL_WMS")" \
deepin "The desktop environment of the Chinese Deepin Linux distribution." "$(ofn deepin "${INSTALL_WMS[*]}")" \ deepin "The desktop environment of the Chinese Deepin Linux distribution." "$(ofn deepin "$INSTALL_WMS")" \
gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "${INSTALL_WMS[*]}")" \ gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "$INSTALL_WMS")" \
cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "${INSTALL_WMS[*]}")" cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "$INSTALL_WMS")"
[[ $INSTALL_WMS ]] || return 0 [[ $INSTALL_WMS ]] || return 0
for i in ${INSTALL_WMS/dwm/}; do for i in ${INSTALL_WMS/dwm/}; do
USERWM_PKGS+=("$i") USERWM_PKGS+=("$i")
done done
@ -649,9 +671,10 @@ select_sessions()
for i in $INSTALL_WMS; do for i in $INSTALL_WMS; do
LOGIN_CHOICES+="$i - " LOGIN_CHOICES+="$i - "
if [[ $i =~ (plasma|deepin) ]]; then if [[ $i =~ (plasma|deepin) ]]; then
local txt="These are larger package groups containing applications that are a part of $i, but are not included in the $i package group." local pretxt="\nThere are some extra packages available for $i that you may want installed:"
yesno "${i^} Extra" \ local txt="These are larger package groups containing applications that are a part of $i"
"\nThere are some extra packages available for $i that you may want installed: ${WM_EXT[$i]}\n\n$txt\n\nWould you like to install them?\n" || continue txt+=" but are not included in the $i package group."
yesno "${i^} Extra" "$pretxt ${WM_EXT[$i]}\n\n$txt\n\nWould you like to install them?\n" || continue
fi fi
if [[ ${WM_EXT[$i]} ]]; then if [[ ${WM_EXT[$i]} ]]; then
for j in ${WM_EXT[$i]}; do for j in ${WM_EXT[$i]}; do
@ -741,7 +764,7 @@ select_packages()
pcmanfm "A fast and lightweight file manager based in Lxde" "$(ofn pcmanfm "${USER_PKGS[*]}")" \ pcmanfm "A fast and lightweight file manager based in Lxde" "$(ofn pcmanfm "${USER_PKGS[*]}")" \
pidgin "Multi-protocol instant messaging client" "$(ofn pidgin "${USER_PKGS[*]}")" \ pidgin "Multi-protocol instant messaging client" "$(ofn pidgin "${USER_PKGS[*]}")" \
plank "An elegant, simple, and clean dock" "$(ofn plank "${USER_PKGS[*]}")" \ plank "An elegant, simple, and clean dock" "$(ofn plank "${USER_PKGS[*]}")" \
playerctl "Mpris media player controller and lib for spotify, vlc, audacious, bmp, xmms2, and others." "$(ofn playerctl "${USER_PKGS[*]}")" \ playerctl "Media player controller for spotify, vlc, audacious, bmp, xmms2, and others." "$(ofn playerctl "${USER_PKGS[*]}")" \
qbittorrent "An advanced bittorrent client" "$(ofn qbittorrent "${USER_PKGS[*]}")" \ qbittorrent "An advanced bittorrent client" "$(ofn qbittorrent "${USER_PKGS[*]}")" \
qpdfview "A tabbed PDF viewer" "$(ofn qpdfview "${USER_PKGS[*]}")" \ qpdfview "A tabbed PDF viewer" "$(ofn qpdfview "${USER_PKGS[*]}")" \
qt5ct "GUI for managing Qt based application themes, icons, and fonts" "$(ofn qt5ct "${USER_PKGS[*]}")" \ qt5ct "GUI for managing Qt based application themes, icons, and fonts" "$(ofn qt5ct "${USER_PKGS[*]}")" \
@ -981,11 +1004,13 @@ part_pretty()
local part="$1" local part="$1"
local regexp="$2" local regexp="$2"
local s dev size isize model local s dev size isize model
[[ $regexp == "" ]] && regexp="part|crypt|lvm"
# invalid block device passed in # invalid block device passed in
[[ $part && ! -b $part ]] && return [[ $part && ! -b $part ]] && return
# full search when not given a regex
[[ $regexp == "" ]] && regexp="part|crypt|lvm"
# string of partitions >= 80M # string of partitions >= 80M
# format: /dev/sda1 447.1G__ext4__unlabeled__Sandisk_SDSSDXP480G # format: /dev/sda1 447.1G__ext4__unlabeled__Sandisk_SDSSDXP480G
while read -r dev size; do while read -r dev size; do
@ -995,9 +1020,9 @@ part_pretty()
isize=${s:0:-1} isize=${s:0:-1}
isize=${isize%.*} isize=${isize%.*}
if [[ $dev = /dev/nvme* ]]; then if [[ $dev = /dev/nvme* ]]; then
model=$(lsblk -lno MODEL "${dev%p[1-9]}" | awk '{gsub(/ /, "_"); print}') model=$(lsblk -lno MODEL "${dev%p[1-9]}" | awk '{gsub(/ |\t/, "_"); print}')
else else
model=$(lsblk -lno MODEL "${dev%[1-9]}" | awk '{gsub(/ /, "_"); print}') model=$(lsblk -lno MODEL "${dev%[1-9]}" | awk '{gsub(/ |\t/, "_"); print}')
fi fi
[[ $size_t == 'K' || ($size_t == 'M' && $isize -lt 80) ]] || printf "%s\n" "$dev ${size}__$model" [[ $size_t == 'K' || ($size_t == 'M' && $isize -lt 80) ]] || printf "%s\n" "$dev ${size}__$model"
done < <(lsblk -lno TYPE,PATH,SIZE,FSTYPE,LABEL $part | done < <(lsblk -lno TYPE,PATH,SIZE,FSTYPE,LABEL $part |
@ -1714,24 +1739,19 @@ install_packages()
loginpkg+=("$i") loginpkg+=("$i")
done done
blk=$(lsblk -f) if [[ $PACSTRAP -eq 1 ]]; then
lspci | grep -qi 'broadcom' && inpkg+=("b43-firmware" "b43-fwcutter" "broadcom-wl") blk=$(lsblk -f)
grep -qi 'ntfs' <<< "$blk" && inpkg+=("ntfs-3g") lspci | grep -qi 'broadcom' && inpkg+=("b43-firmware" "b43-fwcutter" "broadcom-wl")
grep -qi 'jfs' <<< "$blk" && inpkg+=("jfsutils") grep -qi 'ntfs' <<< "$blk" && inpkg+=("ntfs-3g")
grep -qi 'xfs' <<< "$blk" && inpkg+=("xfsprogs") grep -qi 'jfs' <<< "$blk" && inpkg+=("jfsutils")
grep -qi 'btrfs' <<< "$blk" && inpkg+=("btrfs-progs") grep -qi 'xfs' <<< "$blk" && inpkg+=("xfsprogs")
grep -qi 'reiserfs' <<< "$blk" && inpkg+=("reiserfsprogs") grep -qi 'btrfs' <<< "$blk" && inpkg+=("btrfs-progs")
grep -qi 'reiserfs' <<< "$blk" && inpkg+=("reiserfsprogs")
[[ $LVM ]] && inpkg+=("lvm2") [[ $LVM ]] && inpkg+=("lvm2")
[[ $INSTALL_WMS =~ dwm ]] && inpkg+=("git")
[[ $NEWSHELL == "bash" ]] && inpkg+=("bash-completion")
if [[ -d /etc/NetworkManager/system-connections ]]; then
inpkg+=("networkmanager")
elif [[ $(find /etc/network/interfaces -type f) ]]; then
inpkg+=("netctl")
fi fi
[[ $INSTALL_WMS =~ dwm ]] && inpkg+=("git")
[[ $NEWSHELL == "bash" ]] && inpkg+=("bash-completion")
[[ $PACSTRAP != 1 ]] && pacman -Qq archlabs-installer >/dev/null 2>&1 && rmpkg+=("archlabs-installer") [[ $PACSTRAP != 1 ]] && pacman -Qq archlabs-installer >/dev/null 2>&1 && rmpkg+=("archlabs-installer")
if [[ $NEWSHELL == 'zsh' ]]; then if [[ $NEWSHELL == 'zsh' ]]; then
@ -1936,13 +1956,10 @@ install_mirrorlist()
install_background() install_background()
{ {
if [[ -d /etc/NetworkManager/system-connections ]]; then local net="networkmanager"
net="networkmanager" [[ ! -d /etc/NetworkManager/system-connections ]] && net="netctl"
else
net="netctl"
fi
if yesno "Base Install" "$_bginstall" "Pacstrap" "Copy iso"; then if yesno "Background Install" "$_bginstall" "Pacstrap" "Copy ISO"; then
( (
install_mirrorlist "/etc/pacman.d/mirrorlist" > /tmp/bgout 2>&1 && install_mirrorlist "/etc/pacman.d/mirrorlist" > /tmp/bgout 2>&1 &&
pacstrap /mnt base ${ISO_PKGS[*]} $net >> /tmp/bgout 2>&1 && pacstrap /mnt base ${ISO_PKGS[*]} $net >> /tmp/bgout 2>&1 &&
@ -2626,16 +2643,24 @@ dlg()
tput civis tput civis
case "$dlg_t" in case "$dlg_t" in
menu) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2> "$ANS" || return 1 ;; menu)
check) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2> "$ANS" || return 1 ;; dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--menu "$body" 0 0 $n "$@" 2> "$ANS" || return 1
;;
check)
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--checklist "$body" 0 0 $n "$@" 2> "$ANS" || return 1
;;
input) input)
tput cnorm tput cnorm
local def="$1" # assign default value for input local def="$1" # assign default value for input
shift shift
if [[ $1 == 'limit' ]]; then if [[ $1 == 'limit' ]]; then
dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 --title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1 dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 \
--title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1
else else
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1
fi fi
;; ;;
esac esac
@ -2757,14 +2782,19 @@ usage()
yesno() yesno()
{ {
local title="$1" body="$2" yes='Yes' no='No' local title="$1"
local body="$2"
local yes='Yes'
local no='No'
(( $# >= 3 )) && yes="$3" (( $# >= 3 )) && yes="$3"
(( $# >= 4 )) && no="$4" (( $# >= 4 )) && no="$4"
tput civis tput civis
if (( $# == 5 )); then if (( $# == 5 )); then
dialog --backtitle "$DIST Installer - $SYS - v$VER" --defaultno --title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0 dialog --backtitle "$DIST Installer - $SYS - v$VER" --defaultno \
--title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
else else
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
fi fi
} }