#!/bin/sh

# post_setup.sh
# 2022-08-14
# by Gernot WALZL

# Welcome to the post setup process.
# It configures a newly installed Slackware Linux.

URL="https://gernot-walzl.at/Slackware/"

SLACKDIR=${SLACKDIR:-"/mnt/cdrom"}

SETUPDIR=${SETUPDIR:-"/root/setup"}
PKGDIR=${PKGDIR:-"/root/packages"}
SLACKBUILDDIR=${SLACKBUILDDIR:-"/root/slackbuilds"}

EXTRAPKGS="bash-completion mplayerplug-in recordmydesktop
tigervnc tightvnc
wicd"
ADDITIONALPKGS="acpi-scripts firewall-script
homeskel kde-workspace-default-layout
gpg-keys
pkgsums sbopkg+ sbopkg_gui
mozilla-firefox-langpack-de mozilla-firefox-default-profile
mozilla-thunderbird-langpack-de mozilla-thunderbird-dictionary-de-AT mozilla-thunderbird-enigmail
seamonkey-langpack-de
jdk
myutilities"
SLACKBUILDS="unrar
libreoffice libreoffice-langpack libreoffice-helppack
libreoffice-languagetool
vpnc
wine"
USERS="gernot"

SLACKVER=$(awk '{print $2}' /etc/slackware-version)
ARCH=$(uname -m)
TMP=$(mktemp -d)
CWD=$(pwd)

EDITOR=emacs


help () {
  cd "$TMP" || return 1
  cat > help <<EOF
Keep sure that the Slackware Installation DVD is mounted in /mnt/cdrom.

To mount the DVD, execute the following command:
mount /dev/cdrom /mnt/cdrom

If you use an USB stick on sdb:
mount /dev/sdb1 /mnt/cdrom

You can use CTRL-ALT-F? to switch to another terminal.
This is useful if you want to browse the internet using 'links' or
to read the manual pages using 'man'.

GNU Emacs is used to edit configuration files.
The mouse can be used to copy & paste from one to another window.
Some important shortcuts and their corresponding functions:
F10           ... menu-bar-open
CTRL-X CTRL-S ... save-buffer
CTRL-X CTRL-C ... save-buffers-kill-emacs
CTRL-X O      ... other-window
CTRL-S        ... isearch-forward
CTRL-X H      ... mark-whole-buffer
CTRL-X I      ... insert-file
ESC ESC ESC   ... cancel current action
It is not necessary to remember these shortcuts.
Type ALT-X and enter the name of the function. Tab completion works here.

This script was written by Gernot Walzl to speed up the configuration process.
EOF
  $EDITOR help
}


edit_lilo_conf () {
  cd "$TMP" || return 1
  cat > lilo.conf.hints <<EOF
#...
append="quiet rootfstype=ext4 resume=/dev/sda4"
#...
lba32
compact
#ignore-table
#...
# You may disable the Boot BMP Image.
#...
timeout = 50
#...
default = Linux
#...
EOF
  $EDITOR lilo.conf.hints /etc/lilo.conf

  lilo
}


edit_fstab () {
  cd "$TMP" || return 1
  cat > fstab.hints <<EOF
# NTFS
#
# Since kernel 5.15 (Slackware 15.0) there is ntfs3.
# ntfs3 is a kernel space driver, which provides better performance.
# ntfs-3g is a user space driver.

#...
/dev/sda1        /mnt/win7        ntfs        ro,gid=users,fmask=337,dmask=227  0   0
/dev/sda2        /mnt/ntfs        ntfs-3g     gid=users,fmask=113,dmask=002  0   0
/dev/cdrom       /mnt/cdrom       auto        noauto,user,ro,exec  0   0
#...

# Solid State Drives (SSDs)
#
# The kernel defaults to relatime (run "cat /proc/mounts")
#
# discard (trim) does not work reliable on many SSDs.
# In many cases, the firmware of the drive ignores the trim command
# or the drive is blacklisted by the kernel.
# (see /usr/src/linux/drivers/ata/libata-core.c ata_device_blacklist)
#
#/dev/sda3        /                ext4        defaults,noatime,discard  1   1
EOF
  $EDITOR fstab.hints /etc/fstab
}


edit_inputrc () {
  cd "$TMP" || return 1
  cat > inputrc.hints <<EOF
#...
#"\e[5~": beginning-of-history
#"\e[6~": end-of-history
"\e[5~": history-search-backward
"\e[6~": history-search-forward
#...
EOF
  $EDITOR inputrc.hints /etc/inputrc
}


configure_network () {
  if [ -x /usr/bin/nmtui ]; then
    nmtui
  else
    cd "$TMP" || return 1
    cat > rc.inet1.conf.hints <<EOF
#...
IFNAME[1]="wlan0"
IPADDR[1]=""
NETMASK[1]=""
USE_DHCP[1]="yes"
DHCP_HOSTNAME[1]=""
WLAN_WPA[1]="wpa_supplicant"
WLAN_WPADRIVER[1]="nl80211"
WLAN_WPAWAIT[1]="10"
#...
EOF
    $EDITOR rc.inet1.conf.hints /etc/rc.d/rc.inet1.conf

    if grep -e "^WLAN_WPA.*=\"wpa_supplicant\"" /etc/rc.d/rc.inet1.conf ; then
      cat > wpa_supplicant.conf.hints <<EOF
# use wpa_passphrase to pre-compute psk entries
#...
network={
  ssid="OpenWrt"
  psk=0123456789abcdef0123456789abcdef
}
#...
# Plaintext connection (no WPA, no IEEE 802.1X),
# nice for hotel/airport types of WiFi network.
network={
  key_mgmt=NONE
  priority=0
}
EOF
      $EDITOR wpa_supplicant.conf.hints /etc/wpa_supplicant.conf

      cat > rc.inet1.hints <<EOF
#...
# Function to start the network:
start() {
  lo_up
  for i in \${IFNAME[@]} ; do
    if_up \$i &
  done
  wait
  gateway_up
}
#...
EOF
      $EDITOR rc.inet1.hints /etc/rc.d/rc.inet1
    fi

    /etc/rc.d/rc.inet1 restart
  fi
}


run_ntpdate () {
  local NTPSERVER="at.pool.ntp.org"
  echo "ntpdate $NTPSERVER"
  ntpdate $NTPSERVER
}


localize () {
  mkdir -p "$SETUPDIR"
  cd "$SETUPDIR" || return 1
  mount /mnt/cdrom
  if [ ! -f localize_slack.sh ]; then
    wget "${URL}Scripts/setup/localize_slack.sh"
  fi
  chmod +x localize_slack.sh
  SLACKDIR="$SLACKDIR" ./localize_slack.sh
}


install_extra () {
  cd "$TMP" || return 1
  echo "$EXTRAPKGS" > extrapkgs
  dialog --clear --editbox extrapkgs 20 70 2> reply
  local MYREPLY=$(cat reply)
  clear
  mount /mnt/cdrom
  for PKG in $MYREPLY; do
    upgradepkg --install-new ${SLACKDIR}/extra/${PKG}/${PKG}-*.t?z
  done
}


install_pkg_tools () {
  mkdir -p "$PKGDIR"
  cd "$PKGDIR" || return 1;

  #local SBOPKGVER="0.38.2"
  local SBOPKGVER=$(wget -T 10 -q -O - https://www.sbopkg.org/currentversion)
  if [ ! -f "sbopkg-${SBOPKGVER}-noarch-1_wsr.tgz" ]; then
    wget "https://github.com/sbopkg/sbopkg/releases/download/${SBOPKGVER}/sbopkg-${SBOPKGVER}-noarch-1_wsr.tgz"
  fi
  upgradepkg --install-new sbopkg-${SBOPKGVER}-noarch-*.t?z

  local SLAPTGETVER="0.11.6"
  if [ ! -f "slapt-get-${SLAPTGETVER}.tar.gz" ]; then
    wget "https://software.jaos.org/git/slapt-get/snapshot/slapt-get-${SLAPTGETVER}.tar.gz"
  fi
  tar xvf "slapt-get-${SLAPTGETVER}.tar.gz"
  cd "slapt-get-${SLAPTGETVER}" || return 1
  make pkg
  upgradepkg --install-new slapt-get-${SLAPTGETVER}-*.t?z
}


configure_pkg_tools () {
  cd "$TMP" || return 1
  $EDITOR /etc/slackpkg/mirrors
  #$EDITOR /etc/slackpkg/slackpkg.conf

  slackpkg update gpg

  wget http://gernot-walzl.at/About/GPG-KEY
  gpg --import GPG-KEY
  rm GPG-KEY

  if [ -d /etc/slapt-get ]; then
    cat > slapt-getrc.hints <<EOF
# It is important to disable the official slackware repository.
# Official packages will be handled by slackpkg.
#...
# Base url to directory with a PACKAGES.TXT.
# This can point to any release, ie: 9.0, 10.0, current, etc.
# SOURCE=ftp://ftp.slackware.com/pub/slackware/slackware64-${SLACKVER}/:OFFICIAL
#...
# Source for slapt-get.
# SOURCE=http://software.jaos.org/slackpacks/${SLACKVER}-x86_64/:OFFICIAL
#...
# Home made packages.
# SOURCE=file:///var/www/packages/:CUSTOM
SOURCE=http://non:free@gernot-walzl.at/Slackware/Packages/${SLACKVER}-x86_64/:CUSTOM
EOF
    $EDITOR slapt-getrc.hints /etc/slapt-get/slapt-getrc

    slapt-get --add-keys
    slapt-get --update
  fi
}


install_update_daemon () {
  slapt-get -i updated
}


update () {
  /etc/rc.d/rc.updated slackpkg
  if [ -d /etc/slapt-get ]; then
    /etc/rc.d/rc.updated slapt-get
  fi
  if [ -d /etc/sbopkg ]; then
    if grep REPO_BRANCH /etc/sbopkg/sbopkg.conf | grep "$SLACKVER"; then
      /etc/rc.d/rc.updated sbopkg
    fi
  fi
  lilo
  slackpkg new-config
}


slackpkg_blacklist_kernel () {
  if [ "$SLACKVER" = "14.0" -o "$SLACKVER" = "14.1" -o "$SLACKVER" = "14.2" ]; then
    slackpkg blacklist kernel
  else
    if ! grep '^kernel' /etc/slackpkg/blacklist ; then
      echo 'kernel.*' >> /etc/slackpkg/blacklist
    fi
  fi
}


generic_kernel () {
  mkdir -p "$SETUPDIR"
  cd "$SETUPDIR" || return 1
  if [ ! -f generic_kernel.sh ]; then
    wget "${URL}Scripts/setup/generic_kernel.sh"
  fi
  chmod +x generic_kernel.sh
  ./generic_kernel.sh
}


multilib () {
  if [ "$ARCH" != "x86_64" ]; then
    echo "This is not a x86_64 architecture."
    return 1
  fi
  mkdir -p "$SETUPDIR"
  cd "$SETUPDIR" || return 1
  mount /mnt/cdrom
  if [ ! -f multilib.sh ]; then
    wget "${URL}Scripts/setup/multilib.sh"
  fi
  chmod +x multilib.sh
  ./multilib.sh
}


setup_sound () {
  cd "$TMP" || return 1

  if [ $(find /proc/asound -type d -name 'card*' | wc -l) -gt 1 ]; then
    cat > sound.conf.hints <<EOF
alias snd-card-0 snd-hda-intel
alias sound-slot-0 snd-hda-intel
options snd-hda-intel index=0

alias snd-card-2 snd-usb-audio
alias sound-slot-2 snd-usb-audio
options snd-usb-audio index=2
EOF
    $EDITOR sound.conf.hints /etc/modprobe.d/sound.conf
  fi

  alsamixer
  alsactl store
}


install_drivers () {
  if lspci | grep VGA | grep -i nvidia ; then
    local BUMBLEBEE=""
    if lspci | grep VGA | grep -i intel ; then
      local REPLY=""
      echo -n "Do you want to install Bumblebee (NVIDIA Optimus)? [Y/n] "
      read REPLY
      case "$REPLY" in
        n|N) BUMBLEBEE="" ;;
        *) BUMBLEBEE="true" ;;
      esac
    fi
    if [ -z "$BUMBLEBEE" ]; then
      cat > /etc/modprobe.d/BLACKLIST-nouveau.conf <<EOF
# Do not load the kernel nouveau dri module, since it interferes with both
# the nv and binary nvidia drivers.

blacklist nouveau

EOF
      mkdir -p "$SLACKBUILDDIR"
      cd "$SLACKBUILDDIR" || return 1
      local BUILDS="nvidia-kernel nvidia-driver"
      if ! ls /var/log/packages | grep '^libvdpau-' ; then
        BUILDS="libvdpau $BUILDS"
      fi
      for BUILD in $BUILDS ; do
        wget "${URL}SlackBuilds/${BUILD}.SlackBuild"
        chmod +x "${BUILD}.SlackBuild"
        ./${BUILD}.SlackBuild
        upgradepkg --install-new /tmp/${BUILD}-*.t?z
      done
    else
      mkdir -p "$SETUPDIR"
      cd "$SETUPDIR" || return 1
      if [ ! -f bumblebee.sh ]; then
        wget "${URL}Scripts/setup/bumblebee.sh"
      fi
      chmod +x bumblebee.sh
      ./bumblebee.sh
    fi
  else
    echo "No drivers installed."
    return 1
  fi
}


edit_xorg_conf () {
  if [ ! -f /etc/X11/xorg.conf ]; then
    cp /etc/X11/xorg.conf-vesa /etc/X11/xorg.conf
  fi

  cd "$TMP" || return 1
  cat > xorg.conf.hints <<EOF
#...
Section "ServerFlags"
#...
    Option      "standby time"  "0"
    Option      "suspend time"  "0"
    Option      "off time"      "5"
#...

Section "InputDevice"
    Identifier  "Mouse1"
#...
    Option "Protocol"    "IMPS/2"
#...
    Option "ZAxisMapping" "4 5 6 7"
#...

Section "Monitor"
# It should be safe to comment out HorizSync and VertRefresh;
# especially for LCDs.
#...
#    HorizSync   31.5 - 50.0
#...
#    VertRefresh 40-90
#...
    Option "DPMS" "true"
#...

Section "Device"
#...
    Driver      "nvidia"
#    Driver      "radeon"
#    Driver      "intel"   # also for nvidia optimus

# For "nvidia" the following options are recommended:
# Option "UseDisplayDevice" "DFP-1"  # replace with your device
# For notebooks (min power on battery, adaptive on ac)
# Option "RegistryDwords" "PowerMizerEnable=0x1; PowerMizerDefault=0x3; PowerMizerDefaultAC=0x1"

# For "intel" the following options are recommended:
# Option "Backlight" "acpi_video0"

#...

Section "Screen"
#...
    Subsection "Display"
        # add modes of your monitor. e.g. "1920x1080", "1600x900", "1280x720"
#...
EOF
  $EDITOR xorg.conf.hints /etc/X11/xorg.conf
}


#edit_kdmrc () {
#  cd "$TMP" || return 1
#  cat > kdmrc.hints <<EOF
##...
## Core config for local displays
#[X-:*-Core]
##...
#TerminateServer=true
##...
#EOF
#  $EDITOR kdmrc.hints /etc/kde/kdm/kdmrc
#}


install_additional () {
  cd "$TMP" || return 1
  echo "$ADDITIONALPKGS" > additionalpkgs
  dialog --clear --editbox additionalpkgs 20 70 2> reply
  local MYREPLY=$(cat reply)
  clear
  for PKG in $MYREPLY; do
    slapt-get -i "$PKG"
  done
}


install_slackbuilds () {
  cd "$TMP" || return 1
  echo "$SLACKBUILDS" > slackbuilds
  dialog --clear --editbox slackbuilds 20 70 2> reply
  local MYREPLY=$(cat reply)
  clear
  mkdir -p "$SLACKBUILDDIR"
  cd "$SLACKBUILDDIR" || return 1
  for BUILD in $MYREPLY; do
    wget "${URL}SlackBuilds/${BUILD}.SlackBuild"
    chmod +x "${BUILD}.SlackBuild"
    ./${BUILD}.SlackBuild
    upgradepkg --install-new /tmp/${BUILD}-*.t?z
  done
  if [ ! -f sync_slackbuilds.sh ]; then
    wget "${URL}Scripts/sync_slackbuilds.sh"
  fi
  chmod +x sync_slackbuilds.sh
}


add_users () {
  cd "$TMP" || return 1
  echo "$USERS" > users
  dialog --clear --editbox users 20 70 2> reply
  local MYREPLY=$(cat reply)
  clear

  # http://slackbuilds.org/uid_gid.txt
  if [ "$(grep clamav /etc/group)" = "" ]; then
    groupadd -g 210 clamav
    useradd -u 210 -g 210 -c "Clam AntiVirus" -d /dev/null -s /bin/false clamav
  fi
  if [ "$(grep vboxusers /etc/group)" = "" ]; then
    groupadd -g 215 vboxusers
  fi
  if [ "$(grep tor /etc/group)" = "" ]; then
    groupadd -g 220 tor
    useradd -u 220 -g 220 -c "The Onion Router" -d /dev/null -s /bin/false tor
  fi
  if [ "$(grep kvm /etc/group)" = "" ]; then
    groupadd -g 221 kvm
  fi

  for NEWUSER in $MYREPLY; do
    adduser "$NEWUSER"
    clear
  done

  $EDITOR /etc/group
  EDITOR="$EDITOR" visudo
}


edit_rc_local () {
  cd "$TMP" || return 1
  $EDITOR /etc/rc.d/rc.local
  cat > rc.local_shutdown.hints <<EOF
#!/bin/sh
#...
# delete temporary files older than 30 days
/usr/bin/find /tmp -mindepth 1 -mtime +30 -delete 2> /dev/null
EOF
  $EDITOR rc.local_shutdown.hints /etc/rc.d/rc.local_shutdown
  if [ -f /etc/rc.d/rc.local_shutdown ]; then
    chmod +x /etc/rc.d/rc.local_shutdown
  fi
}


edit_inittab () {
  cd "$TMP" || return 1
  cat > inittab.hints <<EOF
#...
# Default runlevel. (Do not set to 0 or 6)
id:4:initdefault:
#...
EOF
  $EDITOR inittab.hints /etc/inittab
}


edit_crontabs_root () {
  cd "$TMP" || return 1
  cat > crontabs_root.hints <<EOF
# May it be that this computer is not up at 4 in the morning?
#...
# Run cron jobs at 00:00 every day:
0 0 * * * /usr/bin/run-parts /etc/cron.midnight 1> /dev/null
EOF
  $EDITOR crontabs_root.hints /var/spool/cron/crontabs/root
  if grep /etc/cron.midnight /var/spool/cron/crontabs/root ; then
    mkdir /etc/cron.midnight
  fi
}


edit_sshd_config () {
  cd "$TMP" || return 1
  cat > sshd_config.hints <<EOF
#...
AllowTcpForwarding yes
#...
X11Forwarding yes
#...
EOF
  $EDITOR sshd_config.hints /etc/ssh/sshd_config
}


set_default_editor () {
  cd "$TMP" || return 1
  cat > editor.sh.hints <<EOF
#!/bin/sh
export EDITOR=/usr/bin/emacs
EOF
  $EDITOR editor.sh.hints /etc/profile.d/editor.sh
  if [ -f /etc/profile.d/editor.sh ]; then
    chmod +x /etc/profile.d/editor.sh
  fi
}


fix_cdrecord_perms () {
  # http://slackware.osuosl.org/slackware64-14.2/CHANGES_AND_HINTS.TXT
  chown root:cdrom /usr/bin/cdrecord /usr/bin/cdrdao
  chmod 4750 /usr/bin/cdrecord /usr/bin/cdrdao
}


upgrade_mplayer () {
  mkdir -p "$SETUPDIR"
  cd "$SETUPDIR" || return 1
  if [ ! -f mencoder_codecs.sh ]; then
    wget "${URL}Scripts/setup/mencoder_codecs.sh"
  fi
  chmod +x mencoder_codecs.sh
  ./mencoder_codecs.sh

  cd "$TMP" || return 1
  cat > mplayer.conf.hints <<EOF
#...
# Specify default video driver (see -vo help for a list).
# If the hardware supports it, vo=vdpau is a better choice.
vo=xv
#...
# Specify default audio driver (see -ao help for a list).
# For Slackware Version >= 14.2:
ao=pulse
# For Slackware Version <= 14.1:
ao=alsa
#...
# Use software volume adjustment
softvol=yes
#...
EOF
  $EDITOR mplayer.conf.hints /etc/mplayer/mplayer.conf
}


while :; do
  SELECTED=1
  if [ "$REPLY" != "" ]; then
    SELECTED=$(("$REPLY" + 1))
  fi
  dialog --default-item "$SELECTED" --menu "Welcome to the post setup process.
It configures a newly installed Slackware Linux." 20 70 12 \
    help "help" \
    1 "edit_lilo_conf" \
    2 "edit_fstab" \
    3 "edit_inputrc" \
    4 "configure_network" \
    5 "run_ntpdate" \
    6 "localize" \
    7 "install_extra" \
    8 "install_pkg_tools" \
    9 "configure_pkg_tools" \
    10 "install_update_daemon" \
    11 "update" \
    12 "slackpkg_blacklist_kernel" \
    13 "generic_kernel" \
    14 "multilib" \
    15 "setup_sound" \
    16 "install_drivers" \
    17 "edit_xorg_conf" \
    18 "install_additional" \
    19 "install_slackbuilds" \
    20 "add_users" \
    21 "edit_rc_local" \
    22 "edit_inittab" \
    23 "edit_crontabs_root" \
    24 "edit_sshd_config" \
    25 "set_default_editor" \
    26 "fix_cdrecord_perms" \
    27 "upgrade_mplayer" \
    2> "${TMP}/reply"
  REPLY=$(cat "${TMP}/reply")
  clear
  case $REPLY in
    help) help ;;
    1) edit_lilo_conf ;;
    2) edit_fstab ;;
    3) edit_inputrc ;;
    4) configure_network ;;
    5) run_ntpdate ;;
    6) localize ;;
    7) install_extra ;;
    8) install_pkg_tools ;;
    9) configure_pkg_tools ;;
    10) install_update_daemon ;;
    11) update ;;
    12) slackpkg_blacklist_kernel ;;
    13) generic_kernel ;;
    14) multilib ;;
    15) setup_sound ;;
    16) install_drivers ;;
    17) edit_xorg_conf ;;
    18) install_additional ;;
    19) install_slackbuilds ;;
    20) add_users ;;
    21) edit_rc_local ;;
    22) edit_inittab ;;
    23) edit_crontabs_root ;;
    24) edit_sshd_config ;;
    25) set_default_editor ;;
    26) fix_cdrecord_perms ;;
    27) upgrade_mplayer ;;
    *) break
  esac
  echo "Press Enter to continue."
  read CONTINUE
done


cd "$CWD"
rm -rf "$TMP"