#!/bin/bash
#
# Copyright 2008, 2009, 2010 Red Hat, Inc.
#
# This file is part of Cygwin.
#
# This software is a copyrighted work licensed under the terms of the
# Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
# details.
#
export PATH="/bin:$PATH"

# Uncomment for testing
# SYSCONFDIR="${PWD}"
SYSCONFDIR="${SYSCONFDIR:=/etc}"

FSTAB="${SYSCONFDIR}/fstab"
MTAB="${SYSCONFDIR}/mtab"
FSTABDIR="${SYSCONFDIR}/fstab.d"

DEVDIR=/dev

print_flags ()
{
  (( $1 & 0x0002 )) && echo -n "binary" || echo -n "text"
  (( $1 & 0x0010 )) && echo -n ",exec"
  (( $1 & 0x0040 )) && echo -n ",cygexec"
  (( $1 & 0x0100 )) && echo -n ",notexec"
}

# Create fstab file if it doesn't exist.
if [ -e "${FSTAB}" -a ! -f "${FSTAB}" ]
then
  # Try to move
  mv -f "${FSTAB}" "${FSTAB}.orig"
  if [ -e "${FSTAB}" -a ! -f "${FSTAB}" ]
  then
    echo
    echo "${FSTAB} is existant but not a file."
    echo "Since this file is specifying the mount points, this might"
    echo "result in unexpected trouble.  Please fix that manually."
    echo
  fi
fi

if [ ! -e "${FSTAB}" ]
then
  # Set IFS to just a LF
  _OLD_IFS="$IFS"
  IFS="
"
  eval $(/bin/mount -m | /bin/sed -n 's%\(.*\) / \([^ ]*\) .*$%CYGROOT="\1" FS_TYPE=\2%p')
  cat > ${FSTAB} << EOF
# For a description of the file format, see the Users Guide
# http://cygwin.com/cygwin-ug-net/using.html#mount-table

EOF

  usr_bin=""
  usr_lib=""

  key='\HKLM\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2'

  # Fetch the old rootdir so we can substitute the old root with the
  # new root on the fly when installing Cygwin into another dir.
  # See the next loop below.  Note that backslash to slash substitution
  # is done immediately, while the space -> \040 substitution is considered
  # dangerous and only done after the root dir substitution.
  for subkey in $(regtool -q list "$key")
  do
    if [ "$subkey" = "/" ]
    then
      OLD_CYGROOT=$(regtool -q get "$key\\$subkey\native")
      OLD_CYGROOT="${OLD_CYGROOT//\\//}"
      break
    fi
  done

  for subkey in $(regtool -q list "$key")
  do
    if [[ "$subkey" =~ /.* ]]
    then
      # Never write out /, /usr/bin, and /usr/lib
      # These are generated automatically by the Cygwin DLL (since 1.7.0-48)
      # and we don't want to give the user ideas.
      [ "$subkey" = "/" ] && continue
      [ "$subkey" = "/usr/bin" ] && continue
      [ "$subkey" = "/usr/lib" ] && continue
      nat=$(regtool -q get "$key\\$subkey\native")
      nat="${nat//\\//}"
      [ -n "${OLD_CYGROOT}" ] && nat="${nat/#${OLD_CYGROOT}/${CYGROOT}}"
      nat="${nat// /\\040}"
      psx="${subkey// /\\040}"
      flags=$(regtool -q get "$key\\$subkey\flags")
      # Skip managed mounts
      if (( ( $flags & 0x0800 ) == 0 ))
      then
	echo -n "${nat} ${psx} some_fs "
	print_flags $flags
	echo " 0 0"
      fi
    fi >> ${FSTAB}
  done
  cygd=""
  prefix=$(regtool -q get "$key\cygdrive prefix")
  flags=$(regtool -q get "$key\cygdrive flags")
  [ -z "$flags" ] && flags=2
  # Don't take system and cygdrive flags into account when testing
  if [ -n "$prefix" \
       -a \( "$prefix" != "/cygdrive" -o "$(( $flags & ~0x28 ))" -ne 2 \) ]
  then
    cygd="1"
    psx="${prefix// /\\040}"
    echo -n "none ${psx} cygdrive "
    print_flags $flags
    echo ",posix=0,user 0 0"
  fi >> ${FSTAB}

  if [ -z "$cygd" ]
  then
    echo "# This is default anyway:" >> ${FSTAB}
    echo "# none /cygdrive cygdrive binary,posix=0,user 0 0" >> ${FSTAB}
  fi
  IFS="$_OLD_IFS"
fi

# Check for ${FSTABDIR} directory

if [ -e "${FSTABDIR}" -a ! -d "${FSTABDIR}" ]
then 
  # No mercy.  Try to remove.
  rm -f "${FSTABDIR}"
  if [ -e "${FSTABDIR}" -a ! -d "${FSTABDIR}" ]
  then 
    echo
    echo "${FSTABDIR} is existant but not a directory."
    echo "Please fix that manually."
    echo
    exit 1
  fi
fi

# Create it if necessary

if [ ! -e "${FSTABDIR}" ]
then
  mkdir -m 1777 "${FSTABDIR}"
  if [ ! -e "${FSTABDIR}" ]
  then
    echo
    echo "Creating ${FSTABDIR} directory failed."
    echo "Please fix that manually."
    echo
    exit 1
  fi
fi

# Check for ${DEVDIR} directory

if [ -e "${DEVDIR}" -a ! -d "${DEVDIR}" ]
then 
  # No mercy.  Try to remove.
  rm -f "${DEVDIR}"
  if [ -e "${DEVDIR}" -a ! -d "${DEVDIR}" ]
  then 
    echo
    echo "${DEVDIR} is existant but not a directory."
    echo "Please fix that manually, otherwise you WILL get problems."
    echo
    exit 1
  fi
fi

# Create it if necessary

if [ ! -e "${DEVDIR}" ]
then
  mkdir -m 755 "${DEVDIR}"
  if [ ! -e "${DEVDIR}" ]
  then
    echo
    echo "Creating ${DEVDIR} directory failed."
    echo "Please fix that manually, otherwise you WILL get problems."
    echo
    exit 1
  fi
fi

# Check for ${DEVDIR}/shm directory (for POSIX semaphores and POSIX shared mem)

if [ -e "${DEVDIR}/shm" -a ! -d "${DEVDIR}/shm" ]
then
  # No mercy.  Try to remove.
  rm -f "${DEVDIR}/shm"
  if [ -e "${DEVDIR}/shm" -a ! -d "${DEVDIR}/shm" ]
  then 
    echo
    echo "${DEVDIR}/shm is existant but not a directory."
    echo "POSIX semaphores and POSIX shared memory will not work"
    echo
  fi
fi

# Create it if necessary

if [ ! -e "${DEVDIR}/shm" ]
then
  mkdir -m 1777 "${DEVDIR}/shm"
  if [ ! -e "${DEVDIR}/shm" ]
  then
    echo
    echo "Creating ${DEVDIR}/shm directory failed."
    echo "POSIX semaphores and POSIX shared memory will not work"
    echo
  fi
else
  chmod 1777 "${DEVDIR}/shm"
fi

# Check for ${DEVDIR}/mqueue directory (for POSIX message queues)

if [ -e "${DEVDIR}/mqueue" -a ! -d "${DEVDIR}/mqueue" ]
then
  # No mercy.  Try to remove.
  rm -f "${DEVDIR}/mqueue"
  if [ -e "${DEVDIR}/mqueue" -a ! -d "${DEVDIR}/mqueue" ]
  then 
    echo
    echo "${DEVDIR}/mqueue is existant but not a directory."
    echo "POSIX message queues will not work"
    echo
  fi
fi

# Create it if necessary

if [ ! -e "${DEVDIR}/mqueue" ]
then
  mkdir -m 1777 "${DEVDIR}/mqueue"
  if [ ! -e "${DEVDIR}/mqueue" ]
  then
    echo
    echo "Creating ${DEVDIR}/mqueue directory failed."
    echo "POSIX message queues will not work"
    echo
  fi
else
  chmod 1777 "${DEVDIR}/mqueue"
fi

# Create /etc/mtab as symlink to /proc/mounts
[ ! -L "${MTAB}" ] && ln -sf /proc/mounts ${MTAB}

# Create default /etc/passwd and /etc/group files
created_passwd=no
created_group=no

if [ ! -e /etc/passwd -a ! -L /etc/passwd ] ; then
  mkpasswd -l -c > /etc/passwd
  chmod 644 /etc/passwd
  created_passwd=yes
fi

if [ ! -e /etc/group -a ! -L /etc/group ] ; then
  mkgroup -l -c > /etc/group
  chmod 644 /etc/group
  created_group=yes
fi

cp -fp /etc/group /tmp/group.mkgroup && \
( [ -w /etc/group ] || chmod --silent a+w /etc/group ; ) && \
echo "root:S-1-5-32-544:0:" > /etc/group && \
sed -e '/root:S-1-5-32-544:0:/d' /tmp/group.mkgroup >> /etc/group && \
chmod --silent --reference=/etc/passwd /etc/group
rm -f /tmp/group.mkgroup

# Deferred to be sure root group entry exists
[ "$created_passwd" = "yes" ] && chgrp --silent root /etc/passwd
[ "$created_group" = "yes"  ] && chgrp --silent root /etc/group

exit 0
