#!/bin/bash

GITUSER=${GITUSER:-git}
GITHOME="/home/$GITUSER"
SELF=`which $0`

case "$1" in
# Public commands

  init) # gitreceive init
    useradd -d $GITHOME $GITUSER || true
    mkdir -p $GITHOME/.ssh
    touch $GITHOME/.ssh/authorized_keys
    cat > $GITHOME/receiver <<EOF
#!/bin/bash
#URL=http://requestb.in/rlh4znrl
#echo "----> Posting to \$URL ..."
#curl \\
#  -X 'POST' \\
#  -F "repository=\$1" \\
#  -F "revision=\$2" \\
#  -F "username=\$3" \\
#  -F "fingerprint=\$4" \\
#  -F contents=@- \\
#  --silent \$URL
EOF
    chmod +x $GITHOME/receiver
    chown -R $GITUSER $GITHOME
    echo "Created receiver script in $GITHOME for user '$GITUSER'."
    ;;

  upload-key) # sudo gitreceive upload-key <username>
    KEY=$(cat)
    FINGERPRINT=$(ssh-keygen -lf /dev/stdin <<< $(echo $KEY) | awk '{print $2}')
    AUTHORIZED_KEYS=$GITHOME/.ssh/authorized_keys
    # When this key is used, use the ssh 'forced command' feature to have 'gitreceive run' to run instead.
    KEY_PREFIX="command=\"$SELF run $2 $FINGERPRINT\",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding,no-port-forwarding"
    echo "$KEY_PREFIX $KEY" >> $AUTHORIZED_KEYS
    echo $FINGERPRINT
    ;;

# Internal commands
  run) 
    export RECEIVE_USER=$2
    export RECEIVE_FINGERPRINT=$3
    # ssh provides the original requested command in $SSH_ORIGINAL_COMMAND
    export RECEIVE_REPO="$(echo $SSH_ORIGINAL_COMMAND | awk '{print $2}' | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
    REPO_PATH="$GITHOME/$RECEIVE_REPO"
    if [ ! -d $REPO_PATH ]; then
      mkdir -p $REPO_PATH
      cd $REPO_PATH
      git init --bare > /dev/null
    fi
    cd $GITHOME
    PRERECEIVE_HOOK="$REPO_PATH/hooks/pre-receive"
    cat > $PRERECEIVE_HOOK <<EOF
#!/bin/bash
cat | $SELF hook
EOF
    chmod +x $PRERECEIVE_HOOK
    git-shell -c "$SSH_ORIGINAL_COMMAND"
    ;;

  hook)
    while read oldrev newrev refname
    do
      # Only run this script for the master branch. You can remove this 
      # if block if you wish to run it for others as well.
      if [[ $refname = "refs/heads/master" ]] ; then
 
        git archive $newrev | $GITHOME/receiver "$RECEIVE_REPO" "$newrev" "$RECEIVE_USER" "$RECEIVE_FINGERPRINT"  
 
        rc=$?
        if [[ $rc != 0 ]] ; then
          echo "      ERROR: failed on rev $newrev - push denied"
          exit $rc
        fi
      fi
    done
    #exit 1 # for debugging
    ;;

  *)
    echo "Usage: gitreceive <command> [options]"
    ;;
esac
