#!/bin/sh

# Postgresql username.
pg_username="postgres"

# Directory where backups go.
backup_dir="/var/lib/postgresql_backup"

# Flag to indicate if the dump file should be compressed.  Set to an
# empty string to not compress the dump.
compress_dump=

do_backup()
{
  database=$1
  shift

  filename=$1
  shift

  echo "  backing up $database"

  test -e $filename.tmp && rm -f $filename.tmp

  /usr/bin/pg_dump -Fc --oids --compress 9 -f $filename.tmp $database

  if test $? -ne 0; then
    echo "$0: pg_dump failed." 2>&1
    return 1
  fi

  if test "$compress_dump"; then
    test -e $filename.tmp.bz2 && rm -f $filename.tmp.bz2
    bzip2 -9 $filename.tmp
    if test $? -ne 0; then
      echo "$0: zip2 -9 $filename.tmp failed." 2>&1
      return 1
    fi

    if test -e $filename.bz2; then
      if test -e $filename.0.bz2; then
        rm -f $filename.0.bz2
        if test $? -ne 0; then
          echo "$0: rm -f $filename.0.bz2 failed." 2>&1
          return 1
        fi
      fi
      mv $filename.bz2 $filename.0.bz2
      if test $? -ne 0; then
        echo "$0: mv $filename.bz2 $filename.0.bz2 failed." 2>&1
        return 1
      fi
    fi
    mv $filename.tmp.bz2 $filename.bz2
    if test $? -ne 0; then
      echo "$0: mv $filename.tmp.bz2 $filename.bz2 failed." 2>&1
      test -e $filename.0.bz2 && mv $filename.0.bz2 $filename.bz2
      return 1
    fi
  else
    if test -e $filename.0; then
      rm -f $filename.0
      if test $? -ne 0; then
        echo "$0: rm -f $filename.0 failed." 2>&1
        return 1
      fi
    fi
    if test -e $filename; then
      mv $filename $filename.0
      if test $? -ne 0; then
        echo "$0: mv $filename $filename.0 failed." 2>&1
        return 1
      fi
    fi
    mv $filename.tmp $filename
    if test $? -ne 0; then
      echo "$0: mv $filename.tmp $filename failed." 2>&1
      test -e $filename.0 && mv $filename.0 $filename
      return 1
    fi
  fi

  return 0
}

if test ! -d "$backup_dir"; then
  echo "$0: backup directory '$backup_dir' does not exist or is not a dir" 1>&2
  exit 1
fi

# Su into the postgres user if we're not as all backups will be done
# as that user.
pg_uid="`/bin/grep ^$pg_username /etc/passwd | /usr/bin/cut -d: -f3`"
if test -z "$pg_uid"; then
  echo "$0: unable to determine postgresql user '$pg_username' uid." 1>&2
  exit 1
fi

my_uid="`/usr/bin/id -u`"
if test -z "$my_uid"; then
  echo "$0: unable to determine my effective uid." 1>&2
  exit 1
fi

case "$my_uid" in
  0)
    exec /bin/su - $pg_username -c "$0"
    ;;
  $pg_uid)
    ;;
  *)
    echo "$0: must run this as root or $pg_username"
    exit 1
    ;;
esac

# Get the list of databases.
pg_databases="`/usr/bin/psql -l \
  | awk 'NF == 5 && \
     $1 != "Name" && \
     $1 != "template0" && \
     $2 == "|" && \
     $3 != "Owner" && \
     $4 == "|" && \
     $5 != "Encoding" \
     {print $1}' \
  | sort`"

umask 0077

cd $backup_dir || exit 1

echo "$0: backing up postgresql database"

status=0
for db in $pg_databases; do
  do_backup $db $db
  if test $? -ne 0; then
    status=1
  fi
done

if test 0 -eq "$status"; then
  echo "$0: backup of postgresql succeeded"
  exit 0
else
  echo "$0: backup of postgresql FAILED" 1>&2
  exit 1
fi
