#!/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=" COMBO1CD/DVDISO fileFolder " 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###