diff options
Diffstat (limited to 'scripts/mkinstall')
-rwxr-xr-x | scripts/mkinstall | 995 |
1 files changed, 814 insertions, 181 deletions
diff --git a/scripts/mkinstall b/scripts/mkinstall index 3ccd20e..7914987 100755 --- a/scripts/mkinstall +++ b/scripts/mkinstall @@ -1,6 +1,6 @@ -#!/bin/sh +#!/bin/bash # -# /sbin/mkinstall - Formilux System Installer - version 1.0.0 - 2003-03-20 +# /sbin/mkinstall - System Installer - version 1.9.1 - 2003-08-02 # This file is part of the Formilux project : http://formilux.ant-computing.com/ # # Copyright (C) 2001-2003 Benoit Dolez & Willy Tarreau @@ -8,12 +8,432 @@ # # This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt ) +cdlist=( ) +names=( ) +sizes=( ) +parts=( ) + +# this utility uses a few temporary files : +# +# /tmp/fsmnt : <device><space><mount_point> +# device=/dev/hda, /dev/sda1... +# space=exactly one space +# mount_mount=/home, /var, /, ..., mbr, cdrom, swap, <empty string when not affected> +# /tmp/fsid : <device><space><hex_id><space><os_name> +# /tmp/fstype : <device><space><fstype> +# /tmp/fslist : <device> +# /tmp/fssize : <device><space><size_in_kB> +# /tmp/sourcepkg : symlink to the source packages directory + +# give it a number suffixed with a k,M,G,T, and it will return it reduced to +# the nearest power of 1024 suffixed with k,M,G or T +humansize() { + local pow val + local -a suff=( "" k M G T P ) + case "${1##[0-9]*}" in + k) pow=1;; + M) pow=2;; + G) pow=3;; + T) pow=4;; + P) pow=5;; + *) pow=0;; + esac + val=${1%%[a-zA-Z]*} + # we don't return values lower than 10 when possible + while [ $val -ge 10240 ]; do + ((pow++)) + ((val/=1024)) + done + REPLY=$val${suff[$pow]} + echo -n $REPLY +} + +detect_cdrom() { + cdlist=($(grep -i '^drive name:' /proc/sys/dev/cdrom/info |cut -f2 -d:)) + CDROMS="${cdlist[*]}" +} + +detect_disks() { + local i j major minor size name rest + + names=( ) + sizes=( ) + parts=( ) + + rm -f /tmp/partitions + tail +3 /proc/partitions | sort -k4.1 >/tmp/partitions + while read major minor size name rest; do + if ((i >= 0)); then + names[i]=$name + sizes[i]=$size + parts[i]=1 + fi + ((i++)) + done < /tmp/partitions + + i=0 + while ((i < ${#names[@]})); do + if [ -n "${names[i]}" ]; then + j=0 + while ((j < ${#names[@]})); do + if [ $i -ne $j -a -n "${names[j]}" -a -z "${names[j]##${names[i]}*}" ]; then + names[j]="" + ((parts[i]+=${parts[j]})) + fi + ((j++)) + done + fi + ((i++)) + done + + i=0 j=0 + while ((i < ${#names[@]})); do + if [ -n "${names[i]}" -a "${cdlist[*]##${names[i]}}" = "${cdlist[*]}" ]; then + names[j]=${names[i]} + sizes[j]=${sizes[i]} + ((parts[j]=${parts[i]}-1)) + ((j++)) + fi + + if ((i >= j)); then + unset names[i] parts[i] sizes[i] + names=("${names[@]}") parts=("${parts[@]}") sizes=("${sizes[@]}") + else + ((i++)) + fi + done + # now we have the list of the hard disks : + # names[] contains their name in /dev + # sizes[] contains their size in blocks (1 kB) + # parts[] contains their number of partitions +} + # This function collects some information in /proc and other places. # It should be called ASAP. function init { - #umount /mnt/cdrom >/dev/null 2>&1 # to avoid stupid recursive copying ! - CDROMS=$(grep -i '^drive name:' /proc/sys/dev/cdrom/info |cut -f2- -d:) + #umount /mnt/cdrom >/dev/null 2>&1 # to avoid stupid recursive copying ! + detect_cdrom + detect_disks + mkdir -p $ROOTDIR >/dev/null 2>&1 +} + +# displays the main menu +# if an arg is passed, it will be used as the name entry of the default action. +# it returns the name of the entry in REPLY +# returns 0 if OK, 1 if Cancel/Exit. +function menu_main { + REPLY=$(dialog --title " Formilux Installation Utility " --no-cancel --no-shadow ${1:+--default-item $1 }\ + --menu "Installation Menu\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 14 \ + "PART" "Configure Partitions and File Systems" \ + "SOURCE" "Select Packages Source" \ + "PKG" "Select which Packages to Install" \ + "CONFIG" "Build Configuration" \ + "SAVE" "Save Current Configuration" \ + "LILO" "Run LILO" \ + "UNMOUNT" "Unmount all File Systems" \ + "SHELL" "Get Access to a Shell" \ + "EXIT" "Exit this Utility" 2>&1 | grep -v EXIT) + [ -n "$REPLY" ] +} + + +# presents a list of hard disks and lets the user choose one. +# the default one can be passed in $1 +# returns 0 if OK, 1 if Cancel/Exit. +function menu_harddisk { + local -a args=( ) + local i=0 + local model + while ((i < ${#names[@]})); do + model='unknown model' + [ -e "/proc/ide/${names[i]}/model" ] && model=$(</proc/ide/${names[i]}/model) + args=("${args[@]}" "${names[i]}" "$model, $(humansize ${sizes[i]}k)B, ${parts[i]} part.") + ((i++)) + done + + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow ${1:+--default-item $1 } --menu "\nSelect a Hard Disk to Configure\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 12 "${args[@]}" "EXIT" "Exit this menu" 2>&1 |grep -v EXIT) + [ -n "$REPLY" ] +} + +# presents a list of hard disks partitions and lets the user choose one. +# the disk is passed in $1 +# the default one can be passed in $2 +# returns 0 if OK, 1 if Cancel/Exit. +function menu_partition { + local -a args=( ) + local dev=$1 + local disk=${1##/dev/} + local def=$2 + local mnt + local device size id syst rest + + for device in $(grep "^$dev" /tmp/fslist 2>/dev/null); do + size=$(grep "^$device " /tmp/fssize 2>/dev/null |cut -f2 -d' ') + mnt=$(grep "^$device " /tmp/fsmnt 2>/dev/null |cut -f2 -d' ') + id=$(grep "^$device " /tmp/fsid 2>/dev/null |cut -f2 -d' ') + syst=$(grep "^$device " /tmp/fsid 2>/dev/null |cut -f3 -d' ') + type=$(grep "^$device " /tmp/fstype 2>/dev/null |cut -f2 -d' ') + if [ -z "$mnt" ]; then + def=${def:-${device##/dev/}} + mnt="not assigned" + else + mnt="assigned to $mnt" + fi + if [ -z "$type" ]; then + def=${def:-${device##/dev/}} + type="not formated" + else + type="type $type" + fi + args=("${args[@]}" "${device##/dev/}" "$(humansize ${size}k)B, Id 0x$id($syst), $type, $mnt") + done + + def=${def:-EXIT} + args=("${args[@]}" "CLEAR" "Clear ALL partitions on this disk" "FDISK" "Run fdisk on this disk") + + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow ${def:+--default-item $def} --menu "\nSelect a Partition\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 12 "${args[@]}" "EXIT" "Exit this menu" 2>&1 |grep -v EXIT) + [ -n "$REPLY" ] +} + +# reads the partition table on a disk and updates the associated files : +# /tmp/fslist, /tmp/fssize, /tmp/fsid, /tmp/fsmnt, /tmp/fstype +# the disk device is passed in $1 (/dev/xxx). There's no return code. +function disk_read_part { + local dev=$1 + local disk=${1##/dev/} + local device begin end cyl size id syst rest file + + rm -f /tmp/sfdisk.${disk//\//.} + for file in fslist fssize fsid; do + grep -v "^$dev" /tmp/$file 2>/dev/null >/tmp/${file}-; mv /tmp/${file}- /tmp/$file + done + + for file in fsmnt fstype; do + grep "^$dev" /tmp/$file 2>/dev/null >/tmp/$file.${disk//\//.} + grep -v "^$dev" /tmp/$file 2>/dev/null >/tmp/${file}-; mv /tmp/${file}- /tmp/$file + done + + sfdisk -l $dev | tr '*' ' ' | grep '^/dev/' >/tmp/sfdisk.${disk//\//.} + while read device begin end cyl size id syst rest; do + # let's ignore empty and extended partitions + [ "$id" = "0" -o "$id" = "5" ] && continue + size=${size%+} + echo "$device" >> /tmp/fslist + echo "$device $size" >> /tmp/fssize + echo "$device $id $syst" >> /tmp/fsid + if [ "$id" != "82" ] || grep -q "^$device " /tmp/fsmnt.${disk//\//.} && ! grep -q "^$device swap" /tmp/fsmnt.${disk//\//.} ; then + grep "^$device " /tmp/fsmnt.${disk//\//.} >> /tmp/fsmnt + grep "^$device " /tmp/fstype.${disk//\//.} >> /tmp/fstype + else + echo "$device swap" >> /tmp/fsmnt + # we want to keep a trace of the format status of the swap partition + # instead of assuming it has already been formated + grep "^$device " /tmp/fstype.${disk//\//.} >> /tmp/fstype + #echo "$device swap" >> /tmp/fstype + fi + done < /tmp/sfdisk.${disk//\//.} + rm -f /tmp/sfdisk.${disk//\//.} +} + +# presents a list of possible actions for a partition : +# - change its mount point +# - format it +# the partition is passed in $1 +# if a default choice should be proposed, its name must be in $2 +# returns 0 if OK, 1 if Cancel/Exit. +function menu_setupfs { + local -a args=( ) + local dev=$1 + local def size type strext2s strext2l strext3 strreiser + local mnt + + def=$2 + mnt=$(grep "^$dev " /tmp/fsmnt 2>/dev/null |cut -f2 -d' ') + [ -z "$mnt" ] && { mnt="not assigned" ; def=${def:-"MNT"}; } + + type=$(grep "^$dev " /tmp/fstype 2>/dev/null |cut -f2 -d' ') + [ -z "$type" ] && type="not formated" + + size=$[ ($(grep "^$dev " /tmp/fssize 2>/dev/null | cut -f2 -d' ')+0) / 1024 ] + + args=("MNT" "Change the mount point ($mnt)") + + if [ "$mnt" = "swap" ]; then + args=("${args[@]}" "SWAP" "* mkswap $dev (format as swap)") + args=("${args[@]}" "SWAPC" " mkswap -c $dev (format and check)") + def=${def:-SWAP} + else + strext2s="mke2fs -b 1024 -m 1 -s 1 $dev (format as small Ext2)" + strext2l="mke2fs -b 4096 -s 1 $dev (format as large Ext2)" + strext3="mke2fs -b 4096 -s 1 -j $dev (format as Ext3)" + strreiser="mkreiserfs -h r5 $dev (format as ReiserFS)" + if [ $size -lt 64 ]; then + strext2s="* $strext2s" + strext2l=" $strext2l" + strext3=" $strext3" + strreiser=" $strreiser" + def=${def:-EXT2S} + else + strext2s=" $strext2s" + strext2l=" $strext2l" + strext3="* $strext3" + strreiser=" $strreiser" + def=${def:-EXT3} + fi + + args=("${args[@]}" "EXT2S" "$strext2s" "EXT2L" "$strext2l" "EXT3" "$strext3" "REISER" "$strreiser" ) + fi + args=("${args[@]}" "SHELL" "Get Access to a Shell") + + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow ${def:+--default-item $def} --menu "\nFormat and Mount Point\n\nChoose a mount point for this partition, then select a format command to format it and set its type. The '*' indicates the recommended format.\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 8 "${args[@]}" "EXIT" "Exit this menu" 2>&1 |grep -v EXIT) + [ -n "$REPLY" ] +} + + +# lets the user change a mount point for a partition. +# the partition is passed in $1 +# returns 0 if something changed, else 1. +function menu_mount_point { + local mnt dev type id name + dev=$1 + mnt=$(grep "^$dev " /tmp/fsmnt 2>/dev/null |cut -f2 -d' ') + id=$(grep "^$dev " /tmp/fsid 2>/dev/null |cut -f2 -d' ') + name=$(grep "^$dev " /tmp/fsid 2>/dev/null |cut -f3 -d' ') + type=$(grep "^$dev " /tmp/fstype 2>/dev/null |cut -f2 -d' ') + + REPLY=$mnt + [ -z "$REPLY" -a "$id" = "82" ] && REPLY="swap" + [ -z "$REPLY" ] && ! grep -q " /boot$" /tmp/fsmnt && REPLY="/boot" + [ -z "$REPLY" ] && ! grep -q " /$" /tmp/fsmnt && REPLY="/" + [ -z "$REPLY" ] && ! grep -q " /var$" /tmp/fsmnt && REPLY="/var" + [ -z "$REPLY" ] && ! grep -q " /home$" /tmp/fsmnt && REPLY="/home" + + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow --inputbox "Enter the mount point for partition $dev\n${id:+Partition Id=$id($name)}${type:+${id:+, }Formated as $type}\nEnter 'swap' to force it to become swap\n\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 12 60 $REPLY 2>&1 || echo $mnt) + if [ "$REPLY" != "$mnt" ]; then + (grep -v "^$dev " /tmp/fsmnt 2>/dev/null; echo "$dev $REPLY") >/tmp/fsmnt- + mv /tmp/fsmnt- /tmp/fsmnt + return 0 + else + return 1 + fi +} + + +# lets the user change the package directory +# the entry is checked to be a valid directory +# returns 0 if something changed, else 1. +function menu_pkg_dir { + local old + + old=$(readlink /var/flx-pkg 2>/dev/null) + REPLY=$old + while : ; do + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow --inputbox "Enter the new packages directory\nCurrently set to '$old'\n\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 12 60 $REPLY 2>&1 || echo $old) + if [ "$REPLY" != "$old" ]; then + if [ -d "$REPLY/." ]; then + PKGDIR=$REPLY + rm -f /var/flx-pkg + ln -sf $REPLY /var/flx-pkg + return 0 + else + dialog --title " Formilux Installation Utility " --msgbox "'$REPLY' is not a valid directory. Please try again, or press [Cancel].\n" 8 60 + fi + else + # cancel or no changes + return 1 + fi + done +} + +# ask the user about the desired source of packages for the installation +function menu_select_source { + local -a args=( ) + args=("CDROM" "CD-ROM" "DISK" "Hard disk or USB storage device" "NFS" "Remove file-system over NFS" "DIR" "Pre-mounted directory") + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow --menu "\nSource Packages Selection\n\nChoose from which medium the source packages will be fetched.\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 8 "${args[@]}" "EXIT" "Exit this menu" 2>&1 |grep -v EXIT) + [ -n "$REPLY" ] +} + + +# ask the user about the desired source cdrom +# returns 0 if the CD could be mounted, 1 otherwise. +function menu_select_cdrom { + local -a args=( ) + local cdrom + + umount -l /mnt/cdrom >/dev/null 2>&1 + rm -f /dev/cdrom + rm -f /var/flx-pkg + PKGDIR= + case ${#cdlist[@]} in + 0) + dialog --title " Formilux Installation Utility " --msgbox "No CD-ROM device was detected on this system. Please load manually any appropriate module or choose another source medium." 12 60 ; + rm -f /var/flx-pkg + return 1 + ;; + 1) + ln -sf ${cdlist[0]} /dev/cdrom + if mount /mnt/cdrom >/dev/null 2>&1 ; then + PKGDIR=/mnt/cdrom/pkg + ln -s $PKGDIR /var/flx-pkg + dialog --title " Formilux Installation Utility " --msgbox "/dev/${cdlist[0]} has been selected as the only CD-ROM device, and mounted successfully.\n" 8 60 + return 0 + else + dialog --title " Formilux Installation Utility " --msgbox "/dev/${cdlist[0]} has been selected as the only CD-ROM device, but could not be mounted. Please insert a valid CD-ROM and try again.\n" 8 60 + return 1 + fi + ;; + esac + + args=("AUTO" "Automatically find which drive contains a CD") + for cdrom in "${cdlist[@]}"; do + if [ -e "/proc/ide/$cdrom/model" ]; then + args=("${args[@]}" "$cdrom" "$(cat /proc/ide/$cdrom/model)") + elif [ -z "${cdrom##sr*}" -o -z "${cdrom##scd*}" ]; then + args=("${args[@]}" "$cdrom" "SCSI CD-ROM") + else + args=("${args[@]}" "$cdrom" "Unknown CD-ROM model") + fi + done + + cdrom="${args[0]}" + while [ -z "$PKGDIR" ]; do + rm -f /dev/cdrom + REPLY=$(dialog --title " Formilux Installation Utility " --no-shadow --default-item "$cdrom" --menu "\nCD-ROM\n\nSelect the CD-ROM drive which contains the Formilux CD-ROM you want to use for the installation.\n\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to confirm your choice." 24 80 8 "${args[@]}" "EXIT" "Exit this menu" 2>&1 |grep -v EXIT) + cdrom=$REPLY + case "$REPLY" in + "") + return 1 + ;; + AUTO) + findcdrom + if [ ! -e /dev/cdrom ]; then + dialog --title " Formilux Installation Utility " --msgbox "No drive containing a valid CD-ROM was found. Please insert a valid CD-ROM and try again.\n" 8 60 + continue + fi + ;; + *) + ln -sf $REPLY /dev/cdrom + ;; + esac + if mount /mnt/cdrom >/dev/null 2>&1; then + PKGDIR=/mnt/cdrom/pkg + dialog --title " Formilux Installation Utility " --msgbox "/dev/$(readlink /dev/cdrom) has been selected as the new CD-ROM device, and mounted successfully.\n" 8 60 + return 0 + else + dialog --title " Formilux Installation Utility " --msgbox "/dev/$(readlink /dev/cdrom) has been selected as the new CD-ROM device, but could not be mounted. Please insert a valid CD-ROM and try again.\n" 8 60 + fi + done + return 1 +} + + +# ask the user a question to which he can reply by "yes" or "no". +# A simple message is passed in $1 +# if $2 is NOT EMPTY, the default response will be NO. +# returns 0 if No, 1 if Yes +function menu_yesno { + dialog --title " Formilux Installation Utility " --no-shadow ${2:+--defaultno} --yesno "$1" 12 65 } # user interface functions @@ -32,74 +452,152 @@ function yesno { # function check_directories { - if [ ! -d $ROOTDIR/etc/. ] ; then - if [ -d $ROOTDIR/boot/etc/. ] ; then - ln -s boot/etc $ROOTDIR/etc - else - echo "Can't find 'etc' directory neither in '/' nor in '/boot'" - return 1 - fi - fi - if [ ! -d $ROOTDIR/var/. ] ; then - mkdir $ROOTDIR/var ; fi - if [ ! -d $ROOTDIR/var/tmp ] ; then - mkdir $ROOTDIR/var/tmp ; chmod 1777 $ROOTDIR/var/tmp ; fi - if [ ! -d $ROOTDIR/var/run ] ; then - mkdir $ROOTDIR/var/run ; fi - if [ ! -d $ROOTDIR/var/spool ] ; then - mkdir $ROOTDIR/var/spool ; fi - if [ ! -d $ROOTDIR/var/log ] ; then - mkdir $ROOTDIR/var/log ; fi - if [ ! -d $ROOTDIR/var/cache ] ; then - mkdir $ROOTDIR/var/cache ; fi - if [ ! -d $ROOTDIR/var/adm/. ] ; then - ln -s log $ROOTDIR/var/adm ; fi + if [ ! -d $ROOTDIR/etc/. ] ; then + if [ -d $ROOTDIR/boot/etc/. ] ; then + ln -s boot/etc $ROOTDIR/etc + else + echo "Can't find 'etc' directory neither in '/' nor in '/boot'" + return 1 + fi + fi + [ -d $ROOTDIR/var/. ] || mkdir $ROOTDIR/var + [ -d $ROOTDIR/var/run ] || mkdir $ROOTDIR/var/run + [ -d $ROOTDIR/var/spool ] || mkdir $ROOTDIR/var/spool + [ -d $ROOTDIR/var/cache ] || mkdir $ROOTDIR/var/cache + if [ ! -d $ROOTDIR/var/log ] ; then + mkdir $ROOTDIR/var/log + chown root:log $ROOTDIR/var/log + chmod 2750 $ROOTDIR/var/log + fi + [ -d $ROOTDIR/var/adm/. ] || ln -s log $ROOTDIR/var/adm - return 0 + if [ ! -d $ROOTDIR/var/tmp ] ; then mkdir $ROOTDIR/var/tmp ; chmod 1777 $ROOTDIR/var/tmp ; fi + # /tmp should exist, either as a dir or a link. + if [ ! -e $ROOTDIR/tmp ] ; then mkdir $ROOTDIR/tmp ; chmod 1777 $ROOTDIR/tmp ; fi + + return 0 } # this function lists all hard drives found, but hides CDROMs function list_disks { - for i in `tail +3 /proc/partitions | awk '{print $4}' | grep '\([a-zA-Z]$\)\|\(c[0-9]*d[0-9]*$\)'`; do - if ! echo $CDROMS | grep -qw $i; then - echo $i - fi - done + echo "${names[@]}" + #for i in `tail +3 /proc/partitions | awk '{print $4}' | grep '\([a-zA-Z]$\)\|\(c[0-9]*d[0-9]*$\)'`; do + # if ! echo $CDROMS | grep -qw $i; then + # echo $i + # fi + #done } +# mounts all the new file-systems, and creates the mount points when needed +function mount_new_fs { + local -a mplist=($(sort -k2.1 /tmp/fsmnt 2>/dev/null|cut -f2 -d' ') ) + local fs mp type + + rm -f /tmp/fstab + + echo "/proc /proc proc defaults 0 0" >> /tmp/fstab + echo "#/dev /dev tmpfs size=0,nr_inodes=4096,remount,nosuid 0 0" >> /tmp/fstab + echo "/dev/pts /dev/pts devpts defaults 0 0" >> /tmp/fstab + echo "/dev/cdrom /mnt/cdrom iso9660 defaults,noauto,ro,users,exec 0 0" >> /tmp/fstab + + for mp in "${mplist[@]}"; do + fs=$(grep " $mp\$" /tmp/fsmnt 2>/dev/null|cut -f1 -d' ') + type=$(grep "^$fs " /tmp/fstype 2>/dev/null|cut -f2 -d' ') + if [ "$mp" != "swap" ]; then + mkdir -p -m 0755 $ROOTDIR$mp 2>/dev/null + mount -t $type $fs $ROOTDIR$mp + fi + if [ "$mp" = "/" ]; then + echo "#$fs $mp $type defaults,ro 1 1" >> /tmp/fstab + echo "/dev/root $mp $type defaults,ro 1 1" >> /tmp/fstab + mkdir -p -m 0755 $ROOTDIR/dev $ROOTDIR/proc $ROOTDIR/etc + mount -t proc proc $ROOTDIR/proc # may be needed for compressed files + elif [ "$mp" = "/boot" ]; then + echo "$fs $mp $type defaults,ro 1 2" >> /tmp/fstab + elif [ "$mp" = "swap" ]; then + echo "$fs $mp $type defaults 0 0" >> /tmp/fstab + else + echo "$fs $mp $type defaults 1 2" >> /tmp/fstab + fi + done + echo "/var/empty /var/empty tmpfs size=0,nr_inodes=1,ro,mode=0100,nosuid,nodev 0 0" >> /tmp/fstab +} + +# unmounts all the new file-systems +function unmount_new_fs { + local -a mplist=($(sort -rk 2.1 /proc/mounts 2>/dev/null | cut -f2 -d' ' | grep "^$ROOTDIR") ) + local fs mp type + + for mp in "${mplist[@]}"; do + if [ "$mp" != "swap" ]; then + umount $mp >/dev/null 2>&1 + fi + done +} + + function setup_part { - if [ -e /tmp/devmap -a -e /tmp/fstab ]; then - echo "Filesystems are currently configured this way :" - for i in `cut -f1 -d' ' /tmp/devmap`; do grep "^$i[ ]" /tmp/fstab | awk '{print $1 " => " $2 }'; done - echo "-- end of list --" - yesno "Do you want to change something (y/n) ?" "n" - if [ "$REPLY" != "y" ]; then return 0; fi - cp /tmp/fstab /tmp/fstab- - cp /tmp/devmap /tmp/devmap- - else - touch /tmp/fstab- /tmp/devmap- - fi - - # clean temporary files - rm -rf /tmp/temp.$$ /tmp/fstab /tmp/devmap - - # unmount previously mounted file-systems - for part in $(grep " $ROOTDIR" /proc/mounts|awk '{print $2}'|sort -r); do - umount $part; - done + if [ -e /tmp/devmap -a -e /tmp/fstab ]; then + echo "Filesystems are currently configured this way :" + for i in `cut -f1 -d' ' /tmp/devmap`; do grep "^$i[ ]" /tmp/fstab | awk '{print $1 " => " $2 }'; done + echo "-- end of list --" + yesno "Do you want to change something (y/n) ?" "n" + [ "$REPLY" = "y" ] || return 0 + cp /tmp/fstab /tmp/fstab- + cp /tmp/devmap /tmp/devmap- + else + touch /tmp/fstab- /tmp/devmap- + fi - echo "/proc /proc proc defaults 0 0" >> /tmp/fstab - echo "/dev /dev tmpfs size=0,nr_inodes=4096,,remount 0 0" >> /tmp/fstab - echo "/dev/pts /dev/pts devpts defaults 0 0" >> /tmp/fstab - echo "/dev/cdrom /mnt/cdrom iso9660 defaults,noauto,ro,user 0 0" >> /tmp/fstab + # clean temporary files + rm -rf /tmp/temp.$$ /tmp/fstab /tmp/devmap - echo "/dev/$(readlink /dev/cdrom) /dev/cdrom" >> /tmp/devmap + # unmount previously mounted file-systems + for part in $(grep " $ROOTDIR" /proc/mounts|awk '{print $2}'|sort -r); do + umount $part; + done + + echo "/proc /proc proc defaults 0 0" >> /tmp/fstab + echo "#/dev /dev tmpfs size=0,nr_inodes=4096,remount 0 0" >> /tmp/fstab + echo "/dev/pts /dev/pts devpts defaults 0 0" >> /tmp/fstab + echo "/dev/cdrom /mnt/cdrom iso9660 defaults,noauto,ro,users 0 0" >> /tmp/fstab + + echo "/dev/$(readlink /dev/cdrom) /dev/cdrom" >> /tmp/devmap + (grep -v ' CDROM$' /tmp/mounts 2>/dev/null; echo "/dev/$(readlink /dev/cdrom) CDROM") >/tmp/mounts- && mv /tmp/mounts- /tmp/mounts + + # scan all disk + # for disk in $(list_disks); do + REPLY=${names[0]} + while menu_harddisk $REPLY; do + disk=${REPLY##/dev/} - # scan all disk - for disk in $(list_disks); do # look for all detected partitions - for spart in `sfdisk -l /dev/$disk 2>/dev/null | grep "^/" |tr '*' ' '| cut -f3- -d'/' | awk '{print $1 ":" $6 }'` ; do +# for spart in `sfdisk -l /dev/$disk 2>/dev/null | grep "^/" |tr '*' ' '| cut -f3- -d'/' | awk '{print $1 ":" $6 }'` ; do + + + REPLY= + while { disk_read_part /dev/$disk ; menu_partition /dev/$disk $REPLY; } do + [ -z "$REPLY" ] && break + if [ "$REPLY" = "CLEAR" ] ; then + if menu_yesno "Warning !\n\nThis will erase the partition table for /dev/$disk.\nAll data will be lost.\n\nDo you still want to proceed ?" N; then + dd if=/dev/zero of=/dev/$disk bs=1024 count=1 > /dev/null 2>&1 + (echo o ; echo w ) | fdisk /dev/$disk > /dev/null 2>&1 + fi + REPLY=FDISK + continue + elif [ "$REPLY" = "FDISK" ]; then + fdisk /dev/$disk + REPLY= + continue + else + echo "menu format/mount pour $REPLY" + fi + + + + + # partition name part=`echo $spart|cut -f1 -d:` set -- `echo $spart | tr ':' ' '` @@ -150,10 +648,20 @@ function setup_part { case "$mountpoint" in /) echo "$part /dev/root" >> /tmp/devmap ;; /boot) echo "$part /dev/boot" >> /tmp/devmap ;; - swap) echo "$part /dev/swap" >> /tmp/devmap ; echo "$part swap swap defaults 0 0" >> /tmp/fstab;; + swap) echo "$part /dev/swap" >> /tmp/devmap ; + echo "$part swap swap defaults 0 0" >> /tmp/fstab;; *) echo "$part /dev/fs/$(echo ${mountpoint#/} |tr '/' '.')" >> /tmp/devmap ;; esac + + case "$mountpoint" in + swap) + (grep -v "^$part " /tmp/mounts 2>/dev/null; echo "$part SWAP") >/tmp/mounts- && mv /tmp/mounts- /tmp/mounts;; + *) + (grep -v "^$part " /tmp/mounts 2>/dev/null; echo "$part $mountpoint") >/tmp/mounts- && mv /tmp/mounts- /tmp/mounts;; + esac + + formatcmd='' # format linux partitions if [ $type = 82 -o $type = 83 -o $type = 8e -o $type = fd ] ; then @@ -294,8 +802,10 @@ function setup_config { BOOTDEV=${BOOTDEV:-`echo $ROOTDEV | sed 's/[0-9]\+$//'`} ask "Choose device on which LILO will be installed " $BOOTDEV BOOTDEV=$REPLY - grep -v '/dev/mbr$' /tmp/devmap > $TMP/devmap + grep -v '/dev/\(mbr\|cdrom\)$' /tmp/devmap > $TMP/devmap 2>/dev/null echo "$BOOTDEV /dev/mbr" >> $TMP/devmap + echo "/dev/$(readlink /dev/cdrom) /dev/cdrom" >> $TMP/devmap + # build a new lilo.conf cd $MNT @@ -403,7 +913,7 @@ EOF # if /var is on its own filesystem, /tmp must be a true filesystem too. if grep -q ' \(/dev/fs/var\|/dev/fs/var\.tmp\)$' $TMP/devmap; then if ! grep -q "^[^ ]\+[ ]\+/tmp[ ]" $TMP/fstab; then - echo "/tmp /tmp tmpfs defaults 0 0" >> $TMP/fstab + echo "/tmp /tmp tmpfs defaults,nosuid,nodev 0 0" >> $TMP/fstab fi fi @@ -444,6 +954,10 @@ function do_lilo { # main +ROOTDIR=/var/mount +PKGDIR=/home/pkg +SHELLDIR=/ + init if [ $0 = "mkdisk" ] ; then setup_part && exit 0 ; exit 1 ; @@ -464,132 +978,251 @@ while [ $# -ge 1 -a "$end" -ne 1 ] ; do shift done -ROOTDIR=/mnt/disk -PKGDIR=/home/pkg -SHELLDIR=/ - -action=1 -while [ "$action" != "q" -a "$action" != "Q" ] ; do +action="PART" +while [ -n "$action" ] ; do - ROOTDEV=`mount | grep " on $ROOTDIR " | cut -f1 -d' '` + ROOTDEV=$(mount | grep " on $ROOTDIR " | cut -f1 -d' ') - echo - echo "Possible actions are :" - echo "1: Run fdisk" - echo "2: Setup filesystems" - echo "3: Install packages" - echo "4: Build running config" - echo "5: Save built config for next reboot" - echo "6: Run lilo" - echo "7: Unmount all" - echo "s: Shell" - echo "q: Quit" - - ask "Select an action (1..7/s/q)" "$action" - - if [ "$REPLY" = "q" -o "$REPLY" = "Q" ] ; then break; fi - if [ "$REPLY" = "s" -o "$REPLY" = "S" ] ; then (cd $SHELLDIR; pwd; sh -i); REPLY=$action; continue; fi - - action=`expr $REPLY + 1` - if [ "$action" = 8 ] ; then action=q ; fi - echo - case $REPLY in - 1) +# echo +# echo "Possible actions are :" +# echo "1: Run fdisk" +# echo "2: Setup filesystems" +# echo "3: Install packages" +# echo "4: Build running config" +# echo "5: Save built config for next reboot" +# echo "6: Run lilo" +# echo "7: Unmount all" +# echo "s: Shell" +# echo "q: Quit" +# +# ask "Select an action (1..7/s/q)" "$action" + + menu_main $action + + [ -z "$REPLY" ] && break + + if [ "$REPLY" = "SHELL" ] ; then (cd $SHELLDIR; echo -n "Current directory : "; pwd; bash -i); REPLY=$action; continue; fi + + case $REPLY in + PART) # unmount previously mounted file-systems - for part in $(grep " $ROOTDIR" /proc/mounts|awk '{print $2}'|sort -r); do umount $part; done - - for disk in $(list_disks); do - sfdisk -l /dev/$disk - yesno "Clear partition table for '/dev/$disk' (y/n)?" "n" - if [ "$REPLY" = "y" ] ; then - dd if=/dev/zero of=/dev/$disk bs=1024 count=1 > /dev/null 2>&1 - (echo o ; echo w ) | fdisk /dev/$disk > /dev/null 2>&1 - fi - yesno "Run 'fdisk' for '/dev/$disk' (y/n)" "y" - if [ "$REPLY" = "y" ] ; then - fdisk /dev/$disk - fi - done - SHELLDIR=/ - ;; - 2) - setup_part - SHELLDIR=/ - ;; - 3) - cd / - if [ "$ROOTDEV" != "" ] ; then - ask "Packages directory, or files pattern ($PKGDIR, $PKGDIR/*.lst, *.prf, *.tgz)"$'\n'" " $PKGDIR ; PKGDIR="$REPLY" - if [ -d "$PKGDIR" ]; then - list=`cd $PKGDIR && ls *.prf *.lst *.tgz 2>/dev/null` - else - list=`basename "$PKGDIR"` - PKGDIR=`dirname "$PKGDIR"` - list=$(cd $PKGDIR && echo $list) - fi - echo "Package list :"; (cd $PKGDIR && ls $list); echo - for pack in $list ; do - ask "Install package '$pack' (y/n/./<other dest>) ?" "y" - INSTDIR=/ - if [ "`echo $REPLY | cut -c1`" = "/" ] ; then INSTDIR=$REPLY ; fi - if [ "$REPLY" = "." ]; then break; fi - if [ "$REPLY" != "n" -a "$REPLY" != "N" ] ; then - case "$pack" in - *lst) cat $PKGDIR/$pack | xargs cp --target-directory=$ROOTDIR$INSTDIR -p --parents -d -R -x ;; - *tgz) mkdir -p -m 0755 $ROOTDIR$INSTDIR && tar zpxf $PKGDIR/$pack -C $ROOTDIR$INSTDIR ;; - *prf) flxextract -R $ROOTDIR$INSTDIR -i $PKGDIR/$pack ;; - esac - fi - done - check_directories || exit 1 - fi - SHELLDIR=/ - ;; - 4) - check_directories || exit 1 - if [ "$UPDATE_ONLY" != "n" -a "$UPDATE_ONLY" != "y" ]; then - echo "Existing files can be REPLACED or UPDATED." - yesno "Do you prefer to UPDATE existing files (y/n) ?" "y" - UPDATE_ONLY="$REPLY" - fi - setup_config $ROOTDIR - echo "done." - echo "New files have been written to /tmp/newconf/" - echo "You can check them now by starting a shell." - SHELLDIR=/tmp/newconf - (cd $SHELLDIR ; ls -lart) - ;; - 5) - echo "Saving config (.preinit, startup.rc, config.rc, fstab, lilo.conf, passwd)" - apply_config $ROOTDIR - echo "Saving config ... done." - echo "Updating dynamic files (/etc/formilux/sig.dat, /etc/ld.so.cache) ... " - ldconfig -r $ROOTDIR > /dev/null 2>&1 - - for SYSTEMMAP in `echo $ROOTDIR/boot/System.map-*`; do - KERNVER=${SYSTEMMAP#$ROOTDIR/boot/System.map-} - chroot $ROOTDIR depmod -a -F /boot/System.map-$KERNVER $KERNVER - done - - echo "Signing the filesystem... (this may take a while)" - cd $ROOTDIR ; signfs -x `mount|grep -v ' type \(tmpfs\|ramfs\)'|grep "^/.* $ROOTDIR "| \ - sed "s@^.*$ROOTDIR\([^ ]*\) .*@.\1@"` > /etc/formilux/sig.dat - echo "Updating dynamic files ... done." - SHELLDIR=/ - ;; - 6) - do_lilo - SHELLDIR=/ - ;; - 7) - cd / - for mp in `grep "$ROOTDIR" /proc/mounts | cut -f2 -d' ' | sort -r` ; do - umount -n $mp + #for part in $(grep " $ROOTDIR" /proc/mounts|awk '{print $2}'|sort -r); do umount $part; done + unmount_new_fs + detect_disks + REPLY=${names[0]} + while menu_harddisk $REPLY; do + disk=${REPLY##/dev/} + + #sfdisk -l /dev/$disk + #yesno "Clear partition table for '/dev/$disk' (y/n)?" "n" + REPLY= + while { disk_read_part /dev/$disk ; menu_partition /dev/$disk $REPLY; } do + part=$REPLY + [ -z "$REPLY" ] && break + if [ "$REPLY" = "CLEAR" ] ; then + if menu_yesno "Warning !\n\nThis will erase the partition table for /dev/$disk.\nAll data will be lost.\n\nDo you still want to proceed ?" N; then + dd if=/dev/zero of=/dev/$disk bs=1024 count=1 > /dev/null 2>&1 + (echo o ; echo w ) | fdisk /dev/$disk > /dev/null 2>&1 + fi + REPLY=FDISK + elif [ "$REPLY" = "FDISK" ]; then + fdisk /dev/$disk + REPLY= + else + part=$REPLY + REPLY= + while menu_setupfs /dev/$part $REPLY; do + case "$REPLY" in + SHELL) + (cd $SHELLDIR; echo -n "Current directory : "; pwd; bash -i) + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part auto") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + # goes automatically to default format + REPLY= + ;; + MNT) + menu_mount_point /dev/$part + # goes automatically to default format + REPLY= + ;; + SWAP) + mkswap /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part swap") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + SWAPC) + mkswap -c /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part swap") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + EXT2S) + mke2fs -b 1024 -m 1 -s 1 /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part ext2") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + EXT2L) + mke2fs -b 4096 -s 1 /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part ext2") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + EXT3) + mke2fs -b 4096 -s 1 -j /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part ext3") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + REISER) + mkreiserfs -h r5 /dev/$part + (grep -v "^/dev/$part " /tmp/fstype 2>/dev/null; echo "/dev/$part reiserfs") >/tmp/fstype- + mv /tmp/fstype- /tmp/fstype + REPLY=EXIT + ;; + esac + # this is done to exit right after an mkfs + [ "$REPLY" = "EXIT" ] && break; + done + REPLY= + fi + done + # things might have changed ! + detect_disks + REPLY=/dev/$disk done + # we now have to mount all these file systems + mount_new_fs SHELLDIR=/ + action=SOURCE ;; + SOURCE) + action=SOURCE + while menu_select_source; do + case "$REPLY" in + CDROM) + menu_select_cdrom && break; + ;; + DISK) + menu_select_disk + ;; + NFS) + menu_select_nfs + ;; + DIR) + menu_select_dir + ;; + esac + done + PKGDIR=$(readlink /var/flx-pkg 2>/dev/null) + [ -d "/var/flx-pkg/." ] && action=PKG + ;; + PKG) + cd / + if [ "$ROOTDEV" != "" ] ; then + #ask "Packages directory, or files pattern ($PKGDIR, $PKGDIR/*.lst, *.prf, *.tgz)"$'\n'" " $PKGDIR ; PKGDIR="$REPLY" + #if [ -d "$PKGDIR" ]; then + # list=`cd $PKGDIR && ls *.prf *.lst *.tgz 2>/dev/null` + #else + # list=`basename "$PKGDIR"` + # PKGDIR=`dirname "$PKGDIR"` + # list=$(cd $PKGDIR && echo $list) + #fi + menu_pkg_dir + list=( ); idx=0 + for pack in $(shopt -s nullglob ; cd $PKGDIR && echo *.{prf,tgz}); do + list[idx++]=$pack + list[idx++]="" + if [ -z "${pack##[0-9][0-9][0-9]_*}" ]; then + # pre-selects every numbered package + list[idx++]="on" + else + list[idx++]="off" + fi + done + + list=( $(dialog --title " Formilux Installation Utility " --no-shadow \ + --checklist "Packages Selection\n\n Press <Space> to select/deselect a package.\n Press <Up>/<Down> to select an item.\n Press <Tab> to move between [OK] and [Cancel].\n Press <Enter> to install your selection." 24 80 12 "${list[@]}" 2>&1) ) + + # dialog returns quoted words + eval list=( "${list[@]}" ) + [ ${#list[@]} -gt 0 ] || break + + for pack in "${list[@]}" ; do + case "$pack" in + *tgz) + [ -d "$ROOTDIR" ] || mkdir -p -m 0755 $ROOTDIR + [ -d "$ROOTDIR/etc/formilux" ] || { mkdir -p -m 0750 $ROOTDIR/etc/formilux; chgrp adm $ROOTDIR/etc/formilux; } + echo "### begin $pack ###" >> $ROOTDIR/etc/formilux/install.log + tar zpvxf $PKGDIR/$pack -C $ROOTDIR >> $ROOTDIR/etc/formilux/install.log + echo "### end $pack ###" >> $ROOTDIR/etc/formilux/install.log + ;; + *prf) + [ -d "$ROOTDIR/etc/formilux" ] || { mkdir -p -m 0750 $ROOTDIR/etc/formilux; chgrp adm $ROOTDIR/etc/formilux; } + echo "### begin $pack ###" >> $ROOTDIR/etc/formilux/install.log + rm -f /tmp/${pack##*/}.log + flxextract -R $ROOTDIR -p $PKGDIR -i $PKGDIR/$pack -l /tmp/${pack##*/}.log + cat /tmp/${pack##*/}.log >> $ROOTDIR/etc/formilux/install.log + echo "### end $pack ###" >> $ROOTDIR/etc/formilux/install.log + ;; + esac + done + check_directories || exit 1 + SHELLDIR=/ + action=CONFIG + else + action=PART + fi + ;; + CONFIG) + check_directories || exit 1 + if [ "$UPDATE_ONLY" != "n" -a "$UPDATE_ONLY" != "y" ]; then + echo "Existing files can be REPLACED or UPDATED." + yesno "Do you prefer to UPDATE existing files (y/n) ?" "y" + UPDATE_ONLY="$REPLY" + fi + setup_config $ROOTDIR + echo "done." + echo "New files have been written to /tmp/newconf/" + echo "You can check them now by starting a shell." + SHELLDIR=/tmp/newconf + (cd $SHELLDIR ; ls -lart) + action=SAVE + ;; + SAVE) + echo "Saving config (.preinit, startup.rc, config.rc, fstab, lilo.conf, passwd)" + apply_config $ROOTDIR + echo "Saving config ... done." + echo "Updating dynamic files (/etc/formilux/sig.dat, /etc/ld.so.cache) ... " + ldconfig -r $ROOTDIR > /dev/null 2>&1 + + for SYSTEMMAP in `echo $ROOTDIR/boot/System.map-*`; do + KERNVER=${SYSTEMMAP#$ROOTDIR/boot/System.map-} + chroot $ROOTDIR depmod -a -F /boot/System.map-$KERNVER $KERNVER + done + + echo "Signing the filesystem... (this may take a while)" + cd $ROOTDIR ; signfs -x `mount|grep -v ' type \(tmpfs\|ramfs\)'|grep "^/.* $ROOTDIR "| \ + sed "s@^.*$ROOTDIR\([^ ]*\) .*@.\1@"` > /etc/formilux/sig.dat + echo "Updating dynamic files ... done." + SHELLDIR=/ + action=LILO + ;; + LILO) + do_lilo + SHELLDIR=/ + action=UNMOUNT + ;; + UNMOUNT) + cd / + unmount_new_fs + umount -l /mnt/cdrom >/dev/null 2>&1 + SHELLDIR=/ + action=EXIT + ;; *) - ;; + ;; esac done |