#!/bin/sh
#(c) copyright Barry Kauler 2011, bkhome.org
#license gpl3 (/usr/share/doc/legal)
#110402 first version.
#121102 file DISTRO_SPECS has new variable DISTRO_DB_SUBNAME. ex: for 14.0-based slacko, DISTRO_DB_SUBNAME=slacko14
#130224 update and fixes.
#130227 xz compression for squashfs.

#3builddistro must already have been run. normally configured with kernel modules
#inside sandbox3/rootfs-complete.
#this script extracts all conceivable drivers and files not needed for regular
#usage, to a zdrv.

WKGDIR="`pwd`"
cd sandbox3
[ ! -f rootfs-complete/etc/DISTRO_SPECS ] && exit

. rootfs-complete/etc/DISTRO_SPECS
[ ! "$DISTRO_DB_SUBNAME" ] && DISTRO_DB_SUBNAME="$DISTRO_COMPAT_VERSION" #121102 fallback if DISTRO_DB_SUBNAME not defined in file DISTRO_SPECS.

KERNELVER="`ls -1 rootfs-complete/lib/modules | grep -E '^2|^3' | head -n 1`" #130224

#backup rootfs-complete...
echo "Creating rootfs-completeBABY and zdrvBABY..."
rm -rf rootfs-completeBABY 2>/dev/null
cp -a rootfs-complete rootfs-completeBABY
mkdir -p zdrv
rm -rf zdrvBABY 2>/dev/null
cp -a zdrv zdrvBABY
sync

rm -f $WKGDIR/sandbox3/rootfs-completeBABY/lib/modules/$KERNELVER/modules.*  #130224 precaution in case full depmod was used before.
busybox depmod -b $WKGDIR/sandbox3/rootfs-completeBABY -F $WKGDIR/sandbox3/System.map $KERNELVER


#this code is out of 3builddistro, with changes...
cd rootfs-completeBABY/lib/modules/$KERNELVER #makes it easier to handle find results.
#create a list of essential modules...
echo "Creating must-have lists..."
SOUNDMODS="`find ./kernel/sound/ -type f | sed -e 's/^\.\///g'`" #want all the alsa sound mods.
IPV4MODS="`find ./kernel/net/ipv4 -type f | sed -e 's/^\.\///g'`" #want all the firewall mods.
NETFILTERMODS="`find ./kernel/net/netfilter -type f | sed -e 's/^\.\///g'`"
#IEEE80211MODS="`find ./kernel/net/ieee80211 -type f | sed -e 's/^\.\///g'`" #want all the ieee80211 mods.
IEEE80211MODS="`find ./kernel/net/wireless -type f | sed -e 's/^\.\///g'`" #want all the wireless 80211 mods.
RFKILLMODS="`find ./kernel/net/rfkill -type f | sed -e 's/^\.\///g'`"
MAC80211MODS="`find ./kernel/net/mac80211 -type f | sed -e 's/^\.\///g'`"
WIMAXMODS="`find ./kernel/net/wimax -type f | sed -e 's/^\.\///g'`"
NETWORKMODS="`find ./kernel/drivers/net -type f | grep -vE '/wan/|/appletalk/|/hamradio/' | sed -e 's/^\.\///g'`" #want all the network interface drivers.
UBUNTUMODS=""
[ -d ./kernel/ubuntu ] && UBUNTUMODS="`find ./kernel/ubuntu -type f | grep -vE '/compcache/|/gnbd/|/heci/|/lirc/' | sed -e 's/^\.\///g'`"
MMCMODS="`find ./kernel/drivers/mmc -type f | sed -e 's/^\.\///g'`" #include mmc/sd host drivers.
MEMSTICKMODS="`find ./kernel/drivers/memstick -type f | sed -e 's/^\.\///g'`"
#130224 MISCMODS="`find ./kernel/drivers/misc -type f | sed -e 's/^\.\///g'`"
USBMODS="`find ./kernel/drivers/usb -type f | sed -e 's/^\.\///g'`"
ACPIMODS="`find ./kernel/drivers/acpi -type f | sed -e 's/^\.\///g'`"
AGPMODS="`find ./kernel/drivers/char/agp -type f | sed -e 's/^\.\///g'`"
I2CMODS="`find ./kernel/drivers/i2c -type f | sed -e 's/^\.\///g'`"
PLATFORMMODS="`find ./kernel/drivers/platform -type f | sed -e 's/^\.\///g'`"
BLUETOOTHMODS="`find ./kernel/drivers/bluetooth -type f | sed -e 's/^\.\///g'`"

V4LMODS="`find ./kernel/drivers/media -type f | grep -E '/v4l2|/videobuf|/videodev' | sed -e 's/^\.\///g'`" #130224
UVCMODS="`find ./kernel/drivers/media -type f | grep 'uvc' | sed -e 's/^\.\///g'`" #130224
HWMONMODS="`find ./kernel/drivers/hwmon -type f | sed -e 's/^\.\///g'`"

#k2.6.25.16: kernel/drivers/char/drm, k2.6.27.4: kernel/drivers/gpu/drm...
DRMMODS="`find ./kernel/drivers -type f | grep '/drm/' | sed -e 's/^\.\///g'`"
USBMODEMLIST="cdc-acm.ko pl2303.ko nozomi.ko hso.ko option.ko sierra.ko"
ANALOGMODEMLIST="mwave.ko martian_dev.ko pctel.ko ltserial.ko slamr.ko slusb.ko esscom.ko"
CPUSCALINGMODS="`find ./kernel/drivers/cpufreq -type f | sed -e 's/^\.\///g'`" #100127
ARCHMODS="`find ./kernel/arch -type f | sed -e 's/^\.\///g'`" #130224
CRYPTOMODS="`find ./kernel/crypto -type f | sed -e 's/^\.\///g'`" #100126
#create a list of extra modules... 130224 extended...
EXTRALIST="synaptics_i2c.ko synaptics_usb.ko thermal_sys.ko blkcipher.ko cbc.ko apm.ko cdrom.ko mwave.ko synclink_cs.ko serial_cs.ko lp.ko n_hdlc.ko nvram.ko sonypi.ko generic_serial.ko agpgart.ko ali-agp.ko amd-k7-agp.ko amd64-agp.ko ati-agp.ko intel-agp.ko nvidia-agp.ko sis-agp.ko sworks-agp.ko via-agp.ko blowfish.ko aes.ko arc4.ko crc32c.ko deflate.ko des.ko md5.ko sha1.ko cramfs.ko ext3.ko fat.ko fuse.ko isofs.ko jbd.ko lockd.ko minix.ko msdos.ko nfs.ko nls_cp437.ko nls_cp850.ko nls_cp852.ko nls_iso8859-1.ko nls_iso8859-13.ko nls_iso8859-14.ko nls_iso8859-15.ko nls_iso8859-2.ko nls_iso8859-3.ko nls_iso8859-4.ko nls_iso8859-5.ko nls_iso8859-6.ko nls_iso8859-7.ko nls_iso8859-8.ko nls_iso8859-9.ko nls_utf8.ko ntfs.ko reiserfs.ko smbfs.ko squashfs.ko udf.ko unionfs.ko vfat.ko i2c-core.ko i2c-algo-bit.ko ide-cs.ko ide-tape.ko ide-cd.ko ide-floppy.ko gameport.ko analog.ko pcigame.ko pcspkr.ko psmouse.ko sermouse.ko serport.ko serio.ko evdev.ko joydev.ko input.ko keybdev.ko mousedev.ko crc32.ko crc-ccitt.ko libcrc32c.ko zlib_deflate.ko firmware_class.ko parport_pc.ko parport_serial.ko parport.ko parport_cs.ko i82365.ko pd6729.ko tcic.ko yenta_socket.ko i82092.ko rsrc_nonstatic.ko pcmcia_core.ko ds.ko imm.ko scsi_mod.ko scsi_transport_spi.ko sd_mod.ko sg.ko sr_mod.ko ide-scsi.ko scsi_debug.ko scsi_transport_fc.ko cdc-acm.ko usb-midi.ko usblp.ko audio.ko bluetty.ko usbcore.ko sl811-hcd.ko uhci-hcd.ko ehci-hcd.ko ohci-hcd.ko uhci.ko usb-ohci.ko usb-uhci.ko usbkbd.ko usbhid.ko hid.ko usbmouse.ko usbnet.ko ir-usb.ko usbserial.ko usb-storage.ko scanner.ko printer.ko fan.ko ibm_acpi.ko ac.ko battery.ko processor.ko thermal.ko paride.ko cryptoloop.ko pktcdvd.ko floppy.ko loop.ko 8250_pnp.ko serial_core.ko 8250.ko 8250_pci.ko ndiswrapper.ko ungrab-winmodem.ko cifs.ko ssb.ko pl2303.ko aufs.ko serio_raw.ko ecb.ko output.ko"
#FBMODS="intelfb.ko rivafb.ko sisfb.ko fbcon-vga-planes.ko fbcon-mfb.ko fbgen.ko mdacon.ko neofb.ko tridentfb.ko vgastate.ko vga16fb.ko "
EXTRAMODS=""
for ONEMOD in $EXTRALIST $USBMODEMLIST #$ANALOGMODEMLIST
do
 ONEFND="`find ./ -type f -name $ONEMOD | sed -e 's/^\.\///g'`"
 if [ "$ONEFND" != "" ];then
  EXTRAMODS="$EXTRAMODS
$ONEFND"
 fi
done
cd ../../../../ #back into sandbox3.
CHOSENMODS="$SOUNDMODS
$IPV4MODS
$NETFILTERMODS
$IEEE80211MODS
$RFKILLMODS
$MAC80211MODS
$WIMAXMODS
$NETWORKMODS
$UBUNTUMODS
$MMCMODS
$MEMSTICKMODS
$MISCMODS
$USBMODS
$ACPIMODS
$AGPMODS
$I2CMODS
$PLATFORMMODS
$BLUETOOTHMODS
$V4LMODS
$UVCMODS
$HWMONMODS
$DRMMODS
$CPUSCALINGMODS
$ARCHMODS
$CRYPTOMODS
$EXTRAMODS"
echo "$CHOSENMODS"| tr -s '\n'  > /tmp/chosenmods.txt
echo "Finding all dependent modules..."
echo -n "" > /tmp/alldeps.txt
echo "$CHOSENMODS" |
while read ONEMOD
do
 [ "$ONEMOD" = "" ] && continue #precaution
 ONEBASE="`basename $ONEMOD`"
 DPATTERN="/${ONEBASE}:"
 PPATTERN="s%^/lib/modules/${KERNELVER}/%%" #130224 not needed anymore. modules.dep format changed awhile back.
 ONEDEPS="`cat rootfs-completeBABY/lib/modules/$KERNELVER/modules.dep | grep "$DPATTERN" | cut -f 2 -d ':' | tr ' ' '\n' | sed -e "$PPATTERN" -e '/^$/d'`" #130224
 [ "$ONEDEPS" != "" ] && echo "$ONEDEPS" >> /tmp/alldeps.txt
done
sync
sort -u /tmp/alldeps.txt > /tmp/alldepssorted.txt #remove duplicate lines.
cat /tmp/alldepssorted.txt >> /tmp/chosenmods.txt
sort -u /tmp/chosenmods.txt > /tmp/allmodssorted.txt
sync
#now move all mods not in the list to zdrv...
echo "Moving unwanted modules to zdrvBABY..."
find rootfs-completeBABY/lib/modules/$KERNELVER/ -type f -name '*.ko' -o -name '*.HIDE' |
while read ONEMODSPEC
do
 ONEMODNAME="`basename $ONEMODSPEC`"
 mPATTERN='/'"$ONEMODNAME"
 if [ "`grep "$mPATTERN" /tmp/allmodssorted.txt`" = "" ];then
  ONEMODPATH="`dirname $ONEMODSPEC`"
  xONEMODPATH="`echo -n "$ONEMODPATH" | sed -e 's%^rootfs\-completeBABY/%%'`"
  mkdir -p zdrvBABY/${xONEMODPATH}
  cp -a $ONEMODSPEC zdrvBABY/${xONEMODPATH}/
  rm -f $ONEMODSPEC
  #move firmware tarball...
  ONEMODBASE="`basename $ONEMODSPEC`"
  ombPATTERN='[:,]'"$ONEMODBASE"
  FWFND="`grep "$ombPATTERN" rootfs-completeBABY/etc/modules/firmware.dep.${KERNELVER} | cut -f 1 -d ':'`"
  if [ "$FWFND" ];then
   if [ -f rootfs-completeBABY/lib/modules/all-firmware/${FWFND}.tar.gz ];then
    mkdir -p zdrvBABY/lib/modules/all-firmware
    mv -f rootfs-completeBABY/lib/modules/all-firmware/${FWFND}.tar.gz zdrvBABY/lib/modules/all-firmware/
   fi
  fi
 fi
done

#special case:
mv -f rootfs-completeBABY/lib/modules/all-firmware/intel537ep.tar.gz zdrvBABY/lib/modules/all-firmware/ 2>/dev/null
cp -a -f --remove-destination rootfs-completeBABY/lib/modules/${KERNELVER}/intelmodem zdrvBABY/lib/modules/${KERNELVER}/ 2>/dev/null
rm -rf rootfs-completeBABY/lib/modules/${KERNELVER}/intelmodem 2>/dev/null

busybox depmod -b $WKGDIR/sandbox3/rootfs-completeBABY -F $WKGDIR/sandbox3/System.map $KERNELVER

WATCHEDDIRS=''

#move scanner drivers...
echo "Moving scanner drivers..."
mkdir -p zdrvBABY/usr/lib
mv -f rootfs-completeBABY/usr/lib/sane zdrvBABY/usr/lib/
mkdir rootfs-completeBABY/usr/lib/sane
WATCHEDDIRS="${WATCHEDDIRS}/usr/lib/sane "

#move printer drivers...
echo "Moving gutenprint printer drivers..."
GUTENVER="`ls -1 rootfs-completeBABY/usr/share/gutenprint | grep '^[0-9]' | head -n 1`"
mkdir -p zdrvBABY/usr/share/gutenprint
mv -f rootfs-completeBABY/usr/share/gutenprint/$GUTENVER zdrvBABY/usr/share/gutenprint/
mkdir -p rootfs-completeBABY/usr/share/gutenprint/$GUTENVER/xml/escp2
WATCHEDDIRS="${WATCHEDDIRS}/usr/share/gutenprint/${GUTENVER} "

#move camera drivers...
echo "Moving libgphoto2 camera drivers..."
PHOTOVER="`ls -1 rootfs-completeBABY/usr/lib/libgphoto2 | grep '^[0-9]' | head -n 1`"
mkdir -p zdrvBABY/usr/lib/libgphoto2
mv -f rootfs-completeBABY/usr/lib/libgphoto2/$PHOTOVER zdrvBABY/usr/lib/libgphoto2/
mkdir -p rootfs-completeBABY/usr/lib/libgphoto2/$PHOTOVER
WATCHEDDIRS="${WATCHEDDIRS}/usr/lib/libgphoto2/${PHOTOVER} "

#move flash player... in fact move media-plugin also...
echo "Moving browser plugins..."
mkdir -p zdrvBABY/usr/lib/mozilla
mv -f rootfs-completeBABY/usr/lib/mozilla/plugins zdrvBABY/usr/lib/mozilla/
mkdir -p rootfs-completeBABY/usr/lib/mozilla/plugins
WATCHEDDIRS="${WATCHEDDIRS}/usr/lib/mozilla/plugins "

#we could also take out a huge chunk of media players...
#TODO

#
if [ ! -f rootfs-completeBABY/usr/bin/inotifywait ];then
 echo
 echo 'ERROR: rootfs-completeBABY/usr/bin/inotifywait does not exist.'
 echo '       the inotify-utils package is required'
fi

#create a monitor daemon to notify if zdrv needs to be installed...
echo '#!/bin/sh
#this daemon monitors for access to certain directories.
#intended to be used with 'baby' build, where extra drivers are in 'zdrv' sfs file.
case $1 in
 start)
  /usr/sbin/inotify-baby &
 ;;
 stop)
  killall inotifywait
 ;;
esac
' > rootfs-completeBABY/etc/init.d/inotify-baby
chmod 755 rootfs-completeBABY/etc/init.d/inotify-baby

cat >rootfs-completeBABY/usr/sbin/inotify-baby <<EOF
#!/bin/sh
#please see /etc/init.d/inotify-baby
inotifywait --quiet ${WATCHEDDIRS} >/tmp/inotify-baby-log
PSFND="\`ps\`"
while [ "\`echo -n "\$PSFND" | grep '\\.xinitrc'\`" = "" ];do
 sleep 1
 PSFND="\`ps\`"
done
BABYLOG="\`cat /tmp/inotify-baby-log | cut -f 1 -d ' '\`"
sleep 5

if [ \$PUPMODE -eq 5  ];then
 ZMSG1="This is a small build, with extra drivers in a separate 'zdrv' file: '\${DISTRO_ZDRVSFS}'.
Note, the extra drivers in 'zdrv' depends on the build -- typically there will be a large number of kernel modules, plus printer, camera, scanner drivers and browser plugins.
As this is the first time that you have booted Puppy, it is highly recommended that you shutdown RIGHT NOW and reboot -- this will save your session, and at next boot you will get another window like this one, asking you to download the 'zdrv'.
Or, if you already know what partition and directory you will be saving the session to (just about everyone who has used Puppy before), then if you have Internet access, you can download the 'zdrv' right now."
 ZMSG2='This window will display again at next bootup!'
else
 ZMSG1="This is a small build, with extra drivers in a separate 'zdrv' file: '\${DISTRO_ZDRVSFS}'.
Please download this and place it in /mnt/home. (\${DISTRO_ZDRVSFS} can be downloaded from same URL you got the live-CD .iso from). Then next time that you bootup this pup, the extra drivers will be automatically loaded. Note, the extra drivers in 'zdrv' depends on the build -- typically there will be a large number of kernel modules, plus printer, camera, scanner drivers and browser plugins."
 ZMSG2='WARNING: This window will not be displayed again!'
 chmod 544 /etc/init.d/inotify-baby #disable
fi

export Z_DIALOG="<window title=\"ZDRV alarm\" icon-name=\"gtk-about\" window_position=\"1\" --decorated=\"false\">
<vbox>
 <text use-markup=\"true\"><label>\"<big><b>IMPORTANT NOTICE</b></big>\"</label></text>
 <text use-markup=\"true\"><label>\"<big>DRIVERS ARE MISSING FROM THE DIRECTORY:
\$BABYLOG</big>\"</label></text>
 <text><label>\"${ZMSG1}\"</label></text>
 <text use-markup=\"true\"><label>\"<big>\${ZMSG2}</big>\"</label></text>
 <frame>
  <hbox>
   <text use-markup=\"true\"><label>\"<big>If you have Internet access, you can download and install the 'zdrv' file '${DISTRO_ZDRVSFS}' right now by clicking this button:</big>\"</label></text>
   <vbox>
   <button>
    <input file>/usr/local/apps/ROX-Filer/ROX/MIME/application-x-squashfs-image.png</input>
    <action type=\"exit\">BUTTON_SFS_DOWNLOAD</action>
   </button>
   </vbox>
  </hbox>
 </frame>
 <hbox>
  <button cancel></button>
 </hbox>
</vbox>
</window>
" 
RETPARAMS="\`gtkdialog --display=:0 --program=Z_DIALOG\`"
[ "\`echo "\$RETPARAMS" | grep 'BUTTON_SFS_DOWNLOAD'\`" = "" ] && exit 1
/usr/sbin/sfsget ${DISTRO_ZDRVSFS}
EOF
chmod 755 rootfs-completeBABY/usr/sbin/inotify-baby

sync
echo "Creating ${DISTRO_ZDRVSFS}BABY..."
[ -f ${DISTRO_ZDRVSFS}BABY ] && rm -f ${DISTRO_ZDRVSFS}BABY
../support/mksquashfs4.2 zdrvBABY ${DISTRO_ZDRVSFS}BABY -comp xz
sync
chmod 644 ${DISTRO_ZDRVSFS}BABY
echo -n "$DISTRO_IDSTRING" >> ${DISTRO_ZDRVSFS}BABY #16-byte id-string appended to file.
sync
md5sum ${DISTRO_ZDRVSFS}BABY > ${DISTRO_ZDRVSFS}BABY.md5.txt

#precaution, as this is a baby build...
rm -f build/${DISTRO_ZDRVSFS} 2>/dev/null

echo "Now building the main f.s., ${DISTRO_PUPPYSFS}BABY..."
sync
rm -f ${DISTRO_PUPPYSFS}BABY 2>/dev/null
../support/mksquashfs4.2 rootfs-completeBABY ${DISTRO_PUPPYSFS}BABY -comp xz
sync
echo -n "$DISTRO_IDSTRING" >> ${DISTRO_PUPPYSFS}BABY #16-byte id-string appended to file.
cp -f ${DISTRO_PUPPYSFS}BABY build/${DISTRO_PUPPYSFS}
sync

#now build the .iso file...
mkisofs -D -R -o ${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}-BABY.iso -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table ./build/
sync
md5sum ${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}-BABY.iso > ${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}-BABY.iso.md5.txt
echo
echo "Would you like to burn it to a CD? "
echo -n "ENTER only for yes, or any printable char then ENTER not to: "
read writeitnow
if [ "$writeitnow" = "" ];then
 CDR=""
 [ -f /etc/cdburnerdevice ] && CDR="/dev/`cat /etc/cdburnerdevice`"
 [ "$CDR" = "" ] && CDR='/dev/sr0'
 CDDESCR="`probedisk2 | grep '|optical|' | grep "$CDR" | cut -f 3 -d '|'`"
 echo -n 'Type "y" for multisession, else just ENTER: '
 read BURNMULTI
 if [ "$BURNMULTI" = "y" ];then
  BURNMULTI="-multi -tao -pad"
 else
  BURNMULTI="-dao"
 fi
 echo "Please insert blank CD into $CDR
(which is described as: ${CDDESCR})
-- also be sure that it is unmounted."
 echo -n "Then hit ENTER key: "
 read yayburn
# $CDRECORD $BURNMULTI -data -eject -v speed=4 padsize=300k dev=ATAPI:$CDR ${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}${SCSIFLAG}.iso
 cdrecord $BURNMULTI -data -eject -v speed=4 padsize=300k dev=$CDR ${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}-BABY.iso
 sync
 eject $CDR
 echo "...done"
fi

###END###
