#!/bin/bash
#
# make an nfsrootdir in /tftpboot/IP
#
#   make the directory structure on /tftpboot/$IP the same as
#   on the server's /etc, but allow the files on etc to be overriden 
#   by eighter /etc/nfsroot/default/etc, or /etc/nfsroot/$IP/etc.
#
# Part of debian package nfsroot
#
# GNU copyleft by joost witteveen <joostje@debian.org>
#


source /etc/nfsroot/def
rm -rf $TMPDIR
mkdir $TMPDIR

#Put the essential files/dirs in the "store" place.
#I do this each time, as it doesn't take much time, and otherwise
#I'd have to check each time to see if they are old.

#echo copying essential bins+dirs  to $STORE_BIN
if test ! -d $STORE_BIN; then mkdir $STORE_BIN; fi
#if this link is old (leftover from old libc, then the link may cause problems.
rm -f $STORE_BIN/lib/libc.so.5
(cd $STORE_BIN; tar -cf - $NEED_BINS | tar -xf -) 2>/dev/null
mkdir $STORE_BIN/etc/init.d 2> /dev/null
#cp /etc/nfsroot/inittab    $STORE_BIN/etc
#cp -p /etc/nfsroot/boot       $STORE_BIN/etc/init.d

check_sane_dir () {
  #this is because hackers make errors, but still would like their
  #systems to not blow up in their face.
  if test "`cd ..;pwd`" = "/"; then
    echo "make_links: pwd only one level from root"
    echo "If you didn't modify the scripts, please report this failure"
    echo "as a bug in nfsroot."
    echo "If you did modify the scripts, you probably did it wrong."
    echo "   (but if you're sure you did it right, backup your `pwd` dir now and"
    echo "   remove the check_sane_dir() call in the make_links* functions)"
    exit 1
  fi
}

condcopyspecial () {
  #this is for the 'special' files /etc/{fstab,initab,init.d/boot}
  #
  from=/etc/nfsroot/$hostip/$1
  if test ! -f "$from"; then
    from=/etc/nfsroot/default/$1
  fi
  #first, copy the file to keep the permissions the same
  cp -a $from $copydir/$1

  #then overwrite it again with the corrected contents.
  cat "$from" | \
    sed -e "s/SERVERIP/$SERVERIP/" -e "s/CLIENTIP/$hostip/"\
    >$copydir/$1
}

function copy_dirs () {
  #to copy directory structure from /etc/nfsroot/{default,$IP} 
  #(first parameter) to /tftpboot/$IP (second parameter).
  #
  # (wanted to do this with tar, but there's no way to make tar non-recursive)

  cd $2;
  cp -a /$1/* $2
 (cd $2; rm `find . -not -type d`)
}

function make_links_ignore () {
  check_sane_dir
  #first, make symlinks to everyghing in $1 (make them to /remote_etc/):
  ln -sf `cd $1; find $f -mindepth 1 -maxdepth 1 |\
            egrep -v -f $ignore |\
            sed -e "s/^\./\/remote_etc$2/"` $copydir/etc/$f 2>/dev/null
  
  #now, we don't want the symlinks in $1 (for example, /etc) to
  #point to that symlink, the symlinks should just be blindly copied.
  LINKS=`cd $1; find $f -type l -mindepth 1 -maxdepth 1 `
  if test "$LINKS"; then
    (cd $copydir/etc; rm -f $LINKS)
    (cd $1; cp -d $LINKS $copydir/etc/$f)
  fi
}
function make_links () {
  check_sane_dir
  ln -sf `cd $1; find $f -mindepth 1 -maxdepth 1 |\
            sed -e "s/^\./\/remote_etc$2/"` $copydir/etc/$f 2>/dev/null

}

function mkhost () {
  host=$1

  fqhostname=`nslookup $host|sed -n "s/^Name: *//p"`
  hostname=`echo $fqhostname |cut -d. -f 1`
  hostip=`nslookup $host|sed -n -e '4,$s/^Address: *//p'`
  
  copydir=/tftpboot/$hostip
  if test -z "$fqhostname" -o -z "$hostname" -o -z "$hostip"; then
    echo "invalid host: $host, fqname=$fqhostname, name=$hostname, ip=$hostip"
    exit
  fi
  ignore=/etc/nfsroot/ignorefiles.$hostip
  if test ! -f $ignore; then
    ignore=/etc/nfsroot/ignorefiles
  fi
  grep -v '^#' $ignore|grep -v '^$' > $TMPDIR/ignore
  ignore=$TMPDIR/ignore
  
  if test "$FORCE" = "y"; then
    rm -rf $copydir
  fi
  if test ! -d $copydir; then
    mkdir $copydir
  else
    echo host $host already installed.
    return 
  fi
  #echo "making dir for: $hostname (full: $fqhostname), IP=$hostip "
  (cd /tftpboot; ln -s $hostip $hostname)

  #for each directory in eighter /etc/nfsroot/default or ../$hostip, mkdir one
  #in /tftpboot/$hostip
  #echo "copying directories in /etc/nfsroot/{default,$hostip} to $copydir"
  copy_dirs /etc/nfsroot/default $copydir
  if test -d /etc/nfsroot/$hostip; then
    copy_dirs /etc/nfsroot/$hostip $copydir
  fi

  #setup the symlinks from /tftpboot/$hostip/etc to /remote_etc, for each 
  #directory in /etc, not found in defaults or $ignore
  cd $copydir/etc
  (cd /;find ./etc -maxdepth 1 -type d| grep -v -f $ignore) >> $TMPDIR/list
  sort $TMPDIR/list | uniq -u|sed -e 's/\.\/etc\///' > $TMPDIR/list1
  cd $copydir/
  cat $TMPDIR/list1 | xargs -i ln -s '/remote_etc/{}' './etc/{}' 2>/dev/null

  #Now, try to creat as many symlinks from /remote_etc to /tftpboot/$hostip/etc
  #as possible (allowed for by the directory structure)
  #echo linking to files in /etc
  cd $copydir
  for f in `cd $copydir/etc;               find . -type d`; do
    make_links_ignore /etc                     ''
  done
  for f in `cd /etc/nfsroot/default/etc;   find . -type d`; do    
    make_links /etc/nfsroot/default/etc "\\/nfsroot\\/default\\/etc"
  done
  if test -d /etc/nfsroot/$hostip -a -d /etc/nfsroot/$hostip/etc; then   
    for f in `cd /etc/nfsroot/$hostip/etc; find .  -type d`; do
    make_links /etc/nfsroot/$hostip/etc "\\/nfsroot\\/$hostip\\/etc"
    done
  fi
  #hard-link the essential binaries, copying the essential devs 
  #echo "making hard links from $STORE_BIN to $copydir"
  for  f in $NEED_BINS; do
    ln -f $STORE_BIN/$f $copydir/$f
  done
  for f in etc/{fstab,inittab,init.d/boot}; do
    rm $copydir/$f
    condcopyspecial $f
  done
  for f in $NEED_DEVS; do
    cp -a -f /$f $copydir/$f
  done
}


for argv in $*; do
  mkhost $argv
done
