#!/bin/bash
#(c) Copyright Barry Kauler, Feb. 2015. License GPL3 (usr/share/doc/legal)
#see also 7build-live-cd in woofQ, /usr/sbin/savesession
#called via "install" icon on desktop.
#150216 first release.
#150219 removed "-processors 1" from mksquashfs.
#150221 introduce full install.
#150228 need LANG=C prefix for printf.
#150303 frugal install, improved final window.
#150317 frugal: create a file in a partition, with ext2 f.s., working area so as not to use ram.
#150317 frugal: move q.sfs out of initrd, save as uncompressed squashfs.
#150318 delete temp wkg-ext2-f.s.-file after using it. tweak size of tmp file.
#150319 fix when run outside quirky live-cd. temp hack.
#150320 fallbacks if 'popup' not available. sanity check for needed utilities.
export TEXTDOMAIN=installquirky
export OUTPUT_CHARSET=UTF-8
#150320 headache, but try get this to work other non-puppy distros...
if [ -f /etc/DISTRO_SPECS ];then
. /etc/DISTRO_SPECS
else
DISTRO_NAME='quirky'
DISTRO_VERSION=0
DISTRO_FILE_PREFIX='quirky'
fi
#. /etc/rc.d/PUPSTATE
touch /etc/rc.d/install.log
INSTALLED_MODE='drive'
. /etc/rc.d/install.log #has INSTALLED_MODE=livecd, frugal, drive (full), partition (full)
USEDZM=`df -m | grep 'zram0' | tr -s ' ' | cut -f 3 -d ' '` #150317
[ ! $USEDZM ] && USEDZM=0 #150319
USEDZM=650 #150319 hack
#150320 fallback if no 'popup' or 'pupmessage':
POPUP='xmessage'
[ `which popup 2>/dev/null` ] && POPUP='popup'
OK="$(gettext 'OK')"
PUPMESSAGE='xmessage'
[ `which pupmessage 2>/dev/null` ] && PUPMESSAGE='pupmessage'
#150320 sanity checks (don't assume existence of 'vercmp'):
FMSGS=''
GDVER=000
[ `which gtkdialog 2>/dev/null` ] && GDVER=`gtkdialog -v | grep '^gtkdialog version' | cut -f 3 -d ' ' | tr -d '.' | cut -c 1-3`
[ ! $GDVER ] && GDVER=000
[ $GDVER -lt 081 ] && FMSGS="${FMSGS}
$(gettext "Sorry, this application requires 'gtkdialog', version 0.8.1 or higher.")"
#'dc' utility is broken in some distros, including fatdog64-700:
DC=''
[ "$(dc 1 2 + p 2>/dev/null)" != "" ] && DC='dc'
[ "$DC" == "" ] && [ "$(busybox dc 1 2 + p 2>/dev/null)" != "" ] && DC='busybox dc'
[ "$DC" == "" ] && FMSGS="${FMSGS}
$(gettext "Sorry, this application requires a working 'dc' utility.")"
if [ "$FMSGS" ];then
case $POPUP in
popup) popup "level=top background=#FF8080 terminate=ok|${FMSGS}" ;;
*) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${FMSGS}" ;;
esac
exit 1
fi
#150317 create a file in a partition, with ext2 f.s., working area so as not to use ram.
create_file_ext2()
{
#$1=DESTDEV, $2=DESTMNTPT
pFREEM=`df -m | grep "^/dev/${1} " | tr -s ' ' | cut -f 4 -d ' '`
pNEEDM3=`expr $USEDZM \* 3` #roughly how much working area needed for frugal install (and future session-saves).
pNEEDM2=`expr $USEDZM \* 2` #roughly how much working area needed for frugal install.
pMSG1="$(gettext 'Install Quirky: partition error')"
pMSG2="$(gettext 'Partition:')"
pMSG4="$(gettext 'Free:')"
pMSG5="$(gettext 'Need:')"
if [ $pFREEM -lt $pNEEDM3 ];then
pMSG3="$(gettext 'Sorry, but this partition needs more free space. Aborting installation.')"
else
dd if=/dev/zero of=${2}/tmpwkgfs.q bs=1M count=${pNEEDM2} conv=fsync #150318
if [ $? -ne 0 ];then
[ -f ${2}/tmpwkgfs.q ] && rm -f ${2}/tmpwkgfs.q
pMSG3="$(gettext 'Sorry, unable to create a file in this partition. Aborting installation.')"
else
sync #redundant
mkfs.ext2 -m 0 ${2}/tmpwkgfs.q
if [ $? -ne 0 ];then
[ -f ${2}/tmpwkgfs.q ] && rm -f ${2}/tmpwkgfs.q
pMSG3="$(gettext 'Sorry, unable to create a file in this partition. Aborting installation.')"
else
sync
return 0 #success.
fi
fi
fi
pupdialog --background '#FF8080' --backtitle "${pMSG1}" --msgbox "${pMSG2} ${1} ${pMSG4} ${pFREEM}MB ${pMSG5} ${pNEEDM}MB
${pMSG3}" 0 0
return 1
}
export IQ_DLG1="
"
RETSTRING1="$(gtkdialog --program=IQ_DLG1 --center)"
[ $? -ne 0 ] && exit
eval "$RETSTRING1"
case "$EXIT" in
##########################################################################
installfrugal)
COMBOITEMS2=""
PARTS="$(probepart -k | grep -E 'ext2|ext3|ext4|f2fs|minix|reiser|ntfs|msdos|fat' | cut -f 3 -d '/')"
[ "$PARTS" == "" ] && exit
for APART in $PARTS
do
DEVA="$(echo -n $APART | cut -f 1 -d '|')"
FSB="$(echo -n $APART | cut -f 2 -d '|')"
ONESIZEK="$(echo -n $APART | cut -f 3 -d '|')"
#code from pmount...
if [ $ONESIZEK -gt 1048576 ];then #1024*1024
ONESIZE="`LANG=C ${DC} $ONESIZEK 1048576 \/ p`" #150228
ONESIZE="`LANG=C printf "%.1f" $ONESIZE`G" #150228
else
if [ $ONESIZEK -gt 99 ];then
ONESIZE="`expr $ONESIZEK \/ 1024`M"
else
ONESIZE="`LANG=C ${DC} $ONESIZEK 1024 \/ p`" #150228
ONESIZE="`LANG=C printf "%.1f" $ONESIZE`M" #150228
fi
fi
[ "$ONESIZE" = "0.0M" ] && ONESIZE=""
COMBOITEMS2="${COMBOITEMS2}- ${DEVA} (${FSB}, ${ONESIZE})
"
done
export IQ_DLG2="
COMBO1- CD/DVD
- ISO file
- Folder
"
RETSTRING2="$(gtkdialog --program=IQ_DLG2 --center)"
[ $? -ne 0 ] && exit
eval "$RETSTRING2"
[ "$EXIT" != "continuefrugal" ] && exit
case "$COMBO1" in
CD/DVD)
SRCFLG='cd'
SRCXML=""
;;
"ISO file")
SRCFLG='iso'
SRCXML="
CHOOSE1/file/downloads600400"
;;
*) #Folder
SRCFLG='dir'
SRCXML="
CHOOSE1/file/downloads600400"
;;
esac
export IQ_DLG2b="
${SRCXML}
COMBO2${COMBOITEMS2}
${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}DESTFOLDER
"
RETSTRING2="$(gtkdialog --program=IQ_DLG2b --center)"
[ $? -ne 0 ] && exit
eval "$RETSTRING2"
[ "$EXIT" != "continuefrugal" ] && exit
if [ "$SRCFLG" == "cd" ];then
#find the CD...
OPTICALS="$(probedisk | grep 'optical' | cut -f 1 -d '|' | cut -f 3 -d '/')"
if [ "$OPTICALS" == "" ];then
eMSG="$(gettext 'Sorry, no optical drives found. Did you insert the CD?')"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
for AOPTICAL in $OPTICALS
do
[ "$AOPTICAL" == "" ] && continue
MNTPT="$(mount | grep "^/dev/${AOPTICAL} " | cut -f 3 -d ' ')"
[ "$MNTPT" != "" ] && break
mkdir -p /mnt/${AOPTICAL}
mount -t iso9660 /dev/${AOPTICAL} /mnt/${AOPTICAL}
if [ $? -eq 0 ];then
MNTPT="/mnt/${AOPTICAL}"
break
fi
done
if [ "$MNTPT" == "" ];then
eMSG="$(gettext 'Sorry, no optical media found.')"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
if [ ! -f ${MNTPT}/initrd.q ];then
eMSG="$(gettext 'Sorry, this is not a Quirky live-CD.')"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
umount $MNTPT
exit
fi
else
#CHOOSE1 has the src file
[ -d "$CHOOSE1" ] && MNTPT="$CHOOSE1"
[ -f "$CHOOSE1" ] && MNTPT="$(dirname "$CHOOSE1")"
if [ "$SRCFLG" == "iso" ];then
FILENAME="$(basename "$CHOOSE1")"
EXT="$(echo -n "$FILENAME" | rev | cut -c 1,2,3,4 | rev)"
if [ "$EXT" != ".iso" -a "$EXT" != ".ISO" ];then
eMSG="$(gettext 'Sorry, this is not an ISO file:') ${FILENAME}"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
mkdir -p /mnt/iso
busybox mount -t iso9660 "$CHOOSE1" /mnt/iso #-o loop not needed.
if [ $? -ne 0 ];then
eMSG="$(gettext 'Sorry, unable to mount:') ${FILENAME}"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
MNTPT="/mnt/iso"
else
FILENAME='initrd.q'
if [ ! -f "$MNTPT"/initrd.q ];then
eMSG="$(gettext 'You chose folder:') ${MNTPT}
$(gettext "Sorry, this does not have the 'vmlinuz' and 'initrd.q' files.")"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
fi
fi
#copy files to destination...
DESTDEV="$(echo -n "$COMBO2" | cut -f 1 -d ' ')"
DESTFS="$(echo -n "$COMBO2" | cut -f 2 -d '(' | cut -f 1 -d ',')"
DESTMNTPT="$(mount | grep "^/dev/${DESTDEV} " | cut -f 3 -d ' ')"
if [ "$DESTMNTPT" == "" ];then
mkdir -p /mnt/${DESTDEV}
mount -t ${DESTFS} /dev/${DESTDEV} /mnt/${DESTDEV}
[ $? -eq 0 ] && DESTMNTPT="/mnt/${DESTDEV}"
fi
if [ "$DESTMNTPT" == "" ];then
eMSG="$(gettext 'Sorry, unable to mount partition:') ${DESTDEV}"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
WAITMSG="$(gettext 'Copying files, please wait...')"
case $POPUP in #150320
popup) popup "placement=center background=#FFC080 level=top|${WAITMSG}" ;; #daemonizes
xmessage) xmessage -bg '#FFC080' -center -buttons '' "${WAITMSG}" & ;;
esac
mkdir -p ${DESTMNTPT}/${DESTFOLDER}
cp -a -f ${MNTPT}/vmlinuz ${DESTMNTPT}/${DESTFOLDER}/
cp -a -f ${MNTPT}/initrd.q ${DESTMNTPT}/${DESTFOLDER}/
RET1=$?
sync
TMPWKGMNTPT=""
if [ $RET1 -eq 0 ];then
#need to remove "install" icon off desktop...
#darn, cannot expand in ntfs/fat partition...
#150317 if not enough ram, create a ext2-file in partition...
mFREEM=`df -m | grep ' /$' | tr -s ' ' | cut -f 4 -d ' '`
pNEEDM2=`expr $USEDZM \* 2` #roughly how much working area needed for frugal install.
if [ $mFREEM -lt $pNEEDM2 ];then
create_file_ext2 $DESTDEV $DESTMNTPT #creates ${DESTMNTPT}/tmpwkgfs.q
RET1=$?
if [ $RET1 -eq 0 ];then
mkdir -p ${DESTMNTPT}/tmpmntpt.q
busybox mount -o loop,rw -t ext2 ${DESTMNTPT}/tmpwkgfs.q ${DESTMNTPT}/tmpmntpt.q
TMPWKGMNTPT="${DESTMNTPT}/tmpmntpt.q"
fi
fi
if [ $RET1 -eq 0 ];then
rm -rf ${TMPWKGMNTPT}/initrd-tree 2>/dev/null
mkdir ${TMPWKGMNTPT}/initrd-tree
cd ${TMPWKGMNTPT}/initrd-tree
cat ${DESTMNTPT}/${DESTFOLDER}/initrd.q | cpio -i -d -m
sync
[ -f ${DESTMNTPT}/${DESTFOLDER}/q.sfs ] && rm -f ${DESTMNTPT}/${DESTFOLDER}/q.sfs
mv -f q.sfs ${DESTMNTPT}/${DESTFOLDER}/q.sfs #150317 move q.sfs outside of the initrd.
unsquashfs -p 1 -d ${TMPWKGMNTPT}/q ${DESTMNTPT}/${DESTFOLDER}/q.sfs
RET1=$?
if [ $RET1 -eq 0 ];then
#see also 7build-live-cd:
sed -i '/installquirky/d' ${TMPWKGMNTPT}/q/root/Choices/ROX-Filer/PuppyPin #remove "install" icon
echo 'INSTALLED_MODE=frugal' >> ${TMPWKGMNTPT}/q/etc/rc.d/install.log
#fix f.s. (as in service_pack's)... should be ok, but do as precaution...
PART2FS="ext2" #zram
tPTN1="s%.*MARK_DEV1FS_LINE.*%DEV1FS='${PART2FS}' #MARK_DEV1FS_LINE %"
sed -i -e "$tPTN1" ${TMPWKGMNTPT}/q/sbin/init
sed -i -e "$tPTN1" ${TMPWKGMNTPT}/q/etc/rc.d/rc.sysinit
#set default for file-chooser in 'savesession' script: 150317 fix:
echo -n "${DESTMNTPT}/${DESTFOLDER}" > ${TMPWKGMNTPT}/q/var/local/frugal-save-remember-mntpt-folder
sync
#now put it together again...
rm -f ${DESTMNTPT}/${DESTFOLDER}/q.sfs
#mksquashfs ${TMPWKGMNTPT}/q q.sfs -comp xz -processors 1
#150219 removed "-processors 1"
#150317 do not compress (removed "-comp xz", instead "-noI -noD -noF -noX -no-exports")...
urxvt -geometry 80x3+0+0 -bg orange -fg black -title "$(gettext 'Rebuilding:') q.sfs $(gettext 'Folder:') ${DESTFOLDER}" -e mksquashfs ${TMPWKGMNTPT}/q ${DESTMNTPT}/${DESTFOLDER}/q.sfs -noI -noD -noF -noX -no-exports
sync
rm -rf ${TMPWKGMNTPT}/q
rm -f ${DESTMNTPT}/${DESTFOLDER}/initrd.q 2> /dev/null
#150317 init script in initrd will read this:
echo -e "BOOT_DEV=${DESTDEV}\nBOOT_FS=${DESTFS}\nBOOT_FOLDER=${DESTFOLDER}" > BOOT_SPECS
sync
find . | cpio -o -H newc > ${DESTMNTPT}/${DESTFOLDER}/initrd.q #.cpio
sync
fi
cd ..
rm -rf initrd-tree
cd /file
fi
fi
sync
if [ "$TMPWKGMNTPT" ];then
umount $TMPWKGMNTPT #150317
rm -f ${DESTMNTPT}/tmpwkgfs.q #150318
sync
fi
umount ${DESTMNTPT}
umount ${MNTPT}
killall $POPUP #150320
if [ $RET1 -ne 0 ];then
eMSG="$(gettext 'Sorry, there was an error. Aborting.')"
case $PUPMESSAGE in
pupmessage) pupmessage -bg '#FF8080' -title "$(gettext 'Quirky Installer: error')" "${eMSG}" ;;
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${eMSG}" ;;
esac
exit
fi
#some gymnastics for working out grub1 drive numbers...
DRV_TYPE="`echo -n "$DESTDEV" | cut -b 1-3`" #ex: sda
GRUB_DRVN=0
for ONE_TYPE in `fdisk -l | grep "^Disk /dev/" | cut -d' ' -f2 | cut -d':' -f1 | tr '\n' ' '`
do
[ "/dev/$DRV_TYPE" = "$ONE_TYPE" ] && break
GRUB_DRVN=`expr $GRUB_DRVN + 1`
done
GRUB_PARTN=`echo -n "$DESTDEV" | cut -b 4-5`
if [ $GRUB_PARTN ];then
GRUB_PARTN=`expr $GRUB_PARTN - 1`
GRUB_PARTN=",$GRUB_PARTN"
fi
GRUB1="title ${DISTRO_NAME} frugal in ${DESTDEV} dir ${DESTFOLDER}
rootnoverify (hd${GRUB_DRVN}${GRUB_PARTN})
kernel /${DESTFOLDER}/vmlinuz rootwait rw
initrd /${DESTFOLDER}/initrd.q"
GRUB4DOSa="title ${DISTRO_NAME} frugal in ${DESTDEV} dir ${DESTFOLDER}
find --set-root --ignore-floppies /${DESTFOLDER}/initrd.q
kernel /${DESTFOLDER}/vmlinuz rootwait rw
initrd /${DESTFOLDER}/initrd.q"
#150303
FSUUID="$(blkid /dev/${DESTDEV} | grep -o 'UUID="[^"]*' | cut -f 2 -d '"')" #'
GRUB4DOSb="title ${DISTRO_NAME} frugal in ${DESTDEV} dir ${DESTFOLDER}
uuid ${FSUUID}
kernel /${DESTFOLDER}/vmlinuz rootwait rw
initrd /${DESTFOLDER}/initrd.q"
export IQ_DLG3="
"
gtkdialog --program=IQ_DLG3 --center
exit
;;
##########################################################################
installdrive)
DRVINSTMSG="$(gettext 'Full install to drive')
$(gettext 'There is not yet an install program.
What you have to do is go to this URL:')
http://distro.ibiblio.org/quirky/quirky6/${DISTRO_TARGETARCH}
$(gettext 'There you will find a *.usfs.xz file, install scripts, and an install-instructions file.')"
case $POPUP in #150320
popup) popup "level=top background=#FF8080 terminate=ok|${DRVINSTMSG}" ;; #daemonizes
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${DRVINSTMSG}" ;;
esac
;;
##########################################################################
installpartition)
DRVINSTMSG="$(gettext 'Full install to partition')
$(gettext 'There is not yet an install program.
What you have to do is go to this URL:')
http://distro.ibiblio.org/quirky/quirky6/${DISTRO_TARGETARCH}
$(gettext 'There you will find a *.usfs.xz file, install scripts, and an install-instructions file.')"
case $POPUP in #150320
popup) popup "level=top background=#FF8080 terminate=ok|${DRVINSTMSG}" ;; #daemonizes
xmessage) xmessage -bg '#FF8080' -center -buttons "${OK}:100" "${DRVINSTMSG}" ;;
esac
;;
##########################################################################
*)
exit
;;
esac
###END###