#!/bin/sh -x

######################################################################
url="https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.3.tar.xz
    ftp://plamo.linet.gr.jp/pub/Plamo-test/kernelsrc_patches/UNICON/vd_unicon-kernel-20130504-3.9.patch
    http://vdlinux.sourceforge.jp/dists/UNICON/vd_unicon-kernel-fonts-20040205.patch.bz2
    git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git
    ftp://plamo.linet.gr.jp/pub/Plamo-test/kernelsrc_patches/mcp/3.9-panic_beep.patch
    ftp://plamo.linet.gr.jp/pub/Plamo-test/kernelsrc_patches/mcp/3.9-morse_code_panics.patch
    ftp://plamo.linet.gr.jp/pub/Plamo-test/kernelsrc_patches/toi/current-tuxonice-for-3.9.2.patch.bz2
    ftp://plamo.linet.gr.jp/pub/Plamo-test/kernelsrc_patches/config-3.9.3-plamo64"
pkgbase=kernel
vers=3.9.3_plamo64
arch=x86_64
build=P1
src=linux-3.9.3
OPT_CONFIG=""
DOCS=""
######################################################################

fscheck() {
  PANGRAM="The quick brown fox jumps over the lazy dog."
  echo -n "Checking for the filesystem ... "
  mkdir pangram ; ( cd pangram ; touch $PANGRAM )
  mv pangram pangram~ ; mkdir pangram ; touch -r pangram~ pangram
  tar cpf pangram.tar pangram ; rmdir pangram ; mv pangram~ pangram
  for i in $PANGRAM ; do tar rpf pangram.tar pangram/$i ; done
  touch -t `date '+%m%d0900'` pangram.tar ; gzip pangram.tar
  touch pangram.tar.gz ; mv pangram.tar.gz pangram1.tgz
  tar cpf pangram.tar pangram
  touch -t `date '+%m%d0900'` pangram.tar ; gzip pangram.tar
  touch pangram.tar.gz ; mv pangram.tar.gz pangram2.tgz
  if cmp -s pangram1.tgz pangram2.tgz ; then
    echo "OK"
    rm -rf pangram pangram1.tgz pangram2.tgz
  else
    echo "NG"
    cat <<- "EOF"
	Hmm, packaging may not be done properly on this filesystem.
	Would you please try again on a default filesystem, thanks!
	
	Happy packaging!!
	
	Quitting...
	EOF
    exit
  fi
}

install2() {
  install -d ${2%/*} ; install -m 644 $1 $2
}

strip_bindir() {
  echo "compressing in $1"
  if [ -d $1 ] ; then (
    shopt -s nullglob
    cd $1
    for i in * ; do
      echo "$i"
      if [ -h $i ] ; then continue ; fi
      if [ -n "`file $i | grep "not stripped"`" ] ; then
         echo "stripping -p $i"
         strip -p $i
      fi
    done
  ) fi
}

strip_libdir() {
  echo "compressing in $1"
  if [ -d $1 ] ; then (
    shopt -s nullglob
    cd $1
    for i in *.so *.so.* *.a ; do
      echo "$i"
      if [ -h $i ] ; then continue ; fi
      if [ -n "`nm -a $i | grep " a "`" ] ; then
        if [ $i != ${i%.a} ] ; then
          echo -n "ranlib and "
          touch -r $i $i.mt ; ranlib $i ; touch -r $i.mt $i ; rm $i.mt
        fi
        echo "stripping -gp $i"
        strip -gp $i
      fi
    done
  ) fi
}

gzip_dir() {
  echo "compressing in $1"
  if [ -d $1 ] ; then (
    cd $1
    files=`ls -f --indicator-style=none | sed '/^\.\{1,2\}$/d'`
    for i in $files ; do
      echo "$i"
      if [ ! -f $i -a ! -h $i -o $i != ${i%.gz} ] ; then continue ; fi
      lnks=`ls -l $i | awk '{print $2}'`
      if [ $lnks -gt 1 ] ; then
        inum=`ls -i $i | awk '{print $1}'`
        for j in `find . -maxdepth 1 -inum $inum` ; do
          if [ ${j#./} == $i ] ; then
            gzip -f $i
          else
            rm -f ${j#./} ; ln $i.gz ${j#./}.gz
          fi
        done
      elif [ -h $i ] ; then
        target=`readlink $i` ; rm -f $i ; ln -s $target.gz $i.gz
      else
        gzip $i
      fi
    done
    for i in $files ; do mv ${i%.gz}.gz $C ; done
    for i in $files ; do mv $C/${i%.gz}.gz . ; done
  ) fi
}

gzip_one() {
  gzip $1 ; mv $1.gz $C ; mv $C/${1##*/}.gz ${1%/*}
}

compress() {
  for i in {$P,$P/usr}/{sbin,bin} ; do strip_bindir $i ; done
  for i in {$P,$P/usr}/lib64 ; do strip_libdir $i ; done
  if [ -f $infodir/dir ] ; then rm -f $infodir/dir ; fi
  gzip_dir $infodir
  for i in `seq 9` n ; do gzip_dir $mandir/man$i ; done
}

prune_symlink() {
  echo "pruning symlink in $1"
  if [ -d $1 ] ; then (
    cd $P
    rm -f /tmp/iNsT-a.$$ ; touch /tmp/iNsT-a.$$
    for i in `find ${1#$P/} -type l` ; do
      target=`readlink $i`
      echo "$i -> $target"
      echo $i$'\n'$target >> /tmp/iNsT-a.$$
    done
    COUNT=1
    LINE=`sed -n "${COUNT}p" /tmp/iNsT-a.$$`
    while [ -n "$LINE" ] ; do
      LINKGOESIN=`dirname $LINE`
      LINKNAMEIS=`basename $LINE`
      COUNT=$(($COUNT + 1))
      LINKPOINTSTO=`sed -n "${COUNT}p" /tmp/iNsT-a.$$`
      if [ ! -d install ] ; then mkdir install ; fi
      cat <<- EOF >> install/doinst.sh
	( cd $LINKGOESIN ; rm -rf $LINKNAMEIS )
	( cd $LINKGOESIN ; ln -sf $LINKPOINTSTO $LINKNAMEIS )
	EOF
      rm -rf $LINE ; touch -t `date '+%m%d0900'` install/doinst.sh $LINE
      COUNT=$(($COUNT + 1))
      LINE=`sed -n "${COUNT}p" /tmp/iNsT-a.$$`
    done
    rm -f /tmp/iNsT-a.$$
  ) fi
}

convert() {
  for i in {$P,$P/usr}/{sbin,bin} ; do prune_symlink $i ; done
  for i in {$P,$P/usr}/lib64 ; do prune_symlink $i ; done
  prune_symlink $infodir
  for i in `seq 9` n ; do prune_symlink $mandir/man$i ; done
}

fscheck
W=`pwd`
for i in `seq 0 $((${#src[@]} - 1))` ; do
  S[$i]=$W/${src[$i]} ; B[$i]=$W/build`test ${#src[@]} -eq 1 || echo $i`
done
P=$W/work ; C=$W/pivot
infodir=$P/usr/share/info
mandir=$P/usr/share/man
docdir=$P/usr/share/doc
myname=`basename $0`
pkg=$pkgbase-$vers-$arch-$build
if [ $# -eq 0 ] ; then
  opt_download=1 ; opt_config=1 ; opt_build=1 ; opt_package=1
else
  opt_download=0 ; opt_config=0 ; opt_build=0 ; opt_package=0
  for i in $@ ; do
    case $i in
    download) opt_download=1 ;;
    config) opt_config=1 ;;
    build) opt_build=1 ;;
    package) opt_package=1 ;;
    esac
  done
fi
if [ $opt_download -eq 1 ] ; then
  for i in $url ; do
    case ${i##*.} in
    xz) if [ ! -f ${i##*/} ] ; then wget --no-check-certificate $i ; fi ;;
    git) if [ ! -d `basename ${i##*/} .git` ] ; then git clone $i ; fi ;;
    *) if [ ! -f ${i##*/} ] ; then wget $i ; fi ;;
    esac
  done
  for i in $url ; do
    case ${i##*.} in
    tar) tar xvpf ${i##*/} ;;
    gz) tar xvpzf ${i##*/} ;;
    bz2) tar xvpjf ${i##*/} ;;
    xz) tar xvpJf ${i##*/} ;;
    git) ( cd `basename ${i##*/} .git`
        git checkout origin/aufs3.x-rcN ; git reset --hard ef8e1b1 ) ;;
    esac
  done
fi
if [ $opt_config -eq 1 ] ; then
  for i in `seq 0 $((${#B[@]} - 1))` ; do
    if [ -d ${B[$i]} ] ; then rm -rf ${B[$i]} ; fi ; cp -a ${S[$i]} ${B[$i]}
  done
  cd $B
  patch -Np1 -i $W/vd_unicon-kernel-20130504-3.9.patch
  bunzip2 -c $W/vd_unicon-kernel-fonts-20040205.patch.bz2 | patch -Np1 -i -
  patch -Np1 -i $W/aufs3-standalone/aufs3-kbuild.patch
  patch -Np1 -i $W/aufs3-standalone/aufs3-base.patch
  patch -Np1 -i $W/aufs3-standalone/aufs3-proc_map.patch
  patch -Np1 -i $W/aufs3-standalone/aufs3-standalone.patch
  cp -av $W/aufs3-standalone/Documentation .
  cp -av $W/aufs3-standalone/fs .
  cp -pv $W/aufs3-standalone/include/linux/aufs_type.h include/linux
  cp -pv $W/aufs3-standalone/include/uapi/linux/aufs_type.h include/uapi/linux
  patch -Np1 -i $W/3.9-panic_beep.patch
  patch -Np1 -i $W/3.9-morse_code_panics.patch
  bunzip2 -c $W/current-tuxonice-for-3.9.2.patch.bz2 | patch -Np1 -i -
  cp -p $W/config-3.9.3-plamo64 .config
  cp -p arch/x86/boot/install.sh{,.orig}
  head -n-9 arch/x86/boot/install.sh.orig > arch/x86/boot/install.sh
  sed -i '/INSTALLKERNEL/s@^@#@g' arch/x86/boot/install.sh
  cat <<- "EOF" | patch arch/x86/boot/install.sh
	48a49
	> cp .config $4/config-$1
	EOF
  sed -i '/\(vmlinuz\|System.map\)$/s@$@-\$1@g' arch/x86/boot/install.sh
  for i in `seq 0 $((${#B[@]} - 1))` ; do
    cd ${B[$i]}
    if [ -f Makefile ] ; then
      make clean
    fi
    if [ -f config.log ] ; then
      rm -rf config.cache config.log
    fi
    if [ -x configure ] ; then
      ./configure --prefix=/usr --libdir='${prefix}'/lib64 \
          --infodir='${prefix}'/share/info \
          --mandir='${prefix}'/share/man ${OPT_CONFIG[$i]}
    fi
  done
fi
if [ $opt_build -eq 1 ] ; then
  for i in `seq 0 $((${#B[@]} - 1))` ; do
    cd ${B[$i]}
    if [ -f Makefile ] ; then
      make
    fi
  done
fi
if [ $opt_package -eq 1 ] ; then
  if [ `id -u` -ne 0 ] ; then
    read -p "Do you want to package as root? [y/N] " ans
    if [ "x$ans" == "xY" -o "x$ans" == "xy" ] ; then
      cd $W ; /bin/su -c "$0 package" ; exit
    fi
  fi
  if [ -d $P ] ; then rm -rf $P ; fi ; mkdir -p $P
  if [ -d $C ] ; then rm -rf $C ; fi ; mkdir -p $C
  touch $W/i.st ; sleep 1
  for i in `seq 0 $((${#B[@]} - 1))` ; do
    cd ${B[$i]}
    if [ -f Makefile ] ; then
      install -d $P/boot
      make install INSTALL_PATH=$P/boot
      make modules_install INSTALL_MOD_PATH=$P
    fi
  done
  krel=${vers//_/-}
  ln -s config-$krel $P/boot/config
  ln -s vmlinuz-$krel $P/boot/vmlinuz
  ln -s System.map-$krel $P/boot/System.map
  rm $P/lib/modules/$krel/{source,build}
  ln -s /usr/src/linux $P/lib/modules/$krel/source
  ln -s /usr/src/linux $P/lib/modules/$krel/build
  touch $W/i.et
  cd $W
  find $P ! -type l -newer i.st ! -newer i.et \
      -exec touch -t `date '+%m%d0900'` {} \;
  compress
  for i in `seq 0 $((${#DOCS[@]} - 1))` ; do
    for j in ${DOCS[$i]} ; do
      for k in ${S[$i]}/$j ; do
        install2 $k $docdir/${src[$i]}/${k#${S[$i]}/}
        touch -r $k $docdir/${src[$i]}/${k#${S[$i]}/}
        gzip_one $docdir/${src[$i]}/${k#${S[$i]}/}
      done
    done
    install -d $docdir/$src
    if [ $i -eq 0 ] ; then
      install $myname $docdir/$src
      touch -t `date '+%m%d0900'` $docdir/$src/$myname
      gzip_one $docdir/$src/$myname
    else
      ln $docdir/$src/$myname.gz $docdir/${src[$i]}
    fi
    ( cd $docdir ; find ${src[$i]} -type d -exec touch -r $W/{} {} \; )
  done
  convert
  prune_symlink $P/boot
  prune_symlink $P/lib/modules/$krel
  touch -t `date '+%m%d0900'` $P/lib/modules/$krel
  tar cvpf $pkg.tar -C $P `cd $P ; find boot | tail -n+2`
  tar rvpf $pkg.tar -C $P lib/modules/$krel
  tar rvpf $pkg.tar -C $P lib/firmware
  tar rvpf $pkg.tar -C $P usr/share/doc/$src
  tar rvpf $pkg.tar -C $P install/doinst.sh
  touch -t `date '+%m%d0900'` $pkg.tar ; xz $pkg.tar ; touch $pkg.tar.xz
  mv $pkg.tar.xz $pkg.txz
  read -p "Do you want to keep work files? [y/N] " ans
  if [ "x$ans" != "xY" -a "x$ans" != "xy" ] ; then rm -rf $P $C i.[se]t ; fi
fi