# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Mobius Forensic Toolkit
# Copyright (C) 2008,2009,2010 Eduardo Aguiar
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import distutils.core
import distutils.command.build
import distutils.command.install
import distutils.command.config
import sys
import re
import glob
import tempfile
import os
import subprocess

PYTHON_REQUIRED_VERSION = (2, 4, 0)
PYGTK_REQUIRED_VERSION = (2, 12, 0)

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Install class
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class Install (distutils.command.install.install):

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Initialize install
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def __init__ (self, *args):
    distutils.command.install.install.__init__ (self, *args)
    self.version = self.distribution.get_version ()

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Run install
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def run (self):
    self.check_python_version ()
    self.check_pygtk ()
    self.check_pygtk_version ()
    self.check_pycairo ()
    self.get_fdgetprm ()
    self.get_fdgetdrvprm ()

    self.install_in ('mobius/config.py')
    self.install_in ('extensions/floppy-imager.xml')

    distutils.command.install.install.run (self)

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Check python version
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def check_python_version (self):
    print 'checking python version...', sys.version.split ()[0]

    if sys.version_info < PYTHON_REQUIRED_VERSION:
      print 'Python %d.%d.%d or newer required. See http://www.python.org' \
          % PYTHON_REQUIRED_VERSION
      sys.exit (2)

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Check pygtk
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def check_pygtk (self):
    print 'checking for PyGTK...',

    try:
      import gtk
      print 'yes'
    except:
      print 'no'
      print 'PyGTK not found. See http://www.pygtk.org'
      sys.exit (2)

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Check pygtk version
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def check_pygtk_version (self):
    import gtk
    print 'checking PyGTK version... %d.%d.%d' % gtk.pygtk_version

    if gtk.pygtk_version < PYGTK_REQUIRED_VERSION:
      print 'PyGTK %d.%d.%d or newer required. See http://www.python.org' \
          % PYGTK_REQUIRED_VERSION
      sys.exit (2)

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Check pycairo
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def check_pycairo (self):
    print 'checking for PyCairo...',

    try:
      import cairo
      print 'yes'
    except:
      print 'no'
      print 'PyCairo not found. See http://cairographics.org/pycairo'
      sys.exit (2)

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Get FDGETPRM
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def get_fdgetprm (self):
    print 'checking FDGETPRM...',

    self.fdgetprm = self.__run_c_code ('''
#include <linux/fd.h>
#include <stdio.h>

int
main ()
{
  printf ("0x%08x", FDGETPRM);
  return 0;
}
''')

    print self.fdgetprm or 'FAIL (Floppy Imager will not work)'
    self.fdgetprm = self.fdgetprm or '-1'

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Get FDGETDRVPRM
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def get_fdgetdrvprm (self):
    print 'checking FDGETDRVPRM...',

    self.fdgetdrvprm = self.__run_c_code ('''
#include <linux/fd.h>
#include <stdio.h>

int
main ()
{
  printf ("0x%08x", FDGETDRVPRM);
  return 0;
}
''')

    print self.fdgetdrvprm or 'FAIL (Floppy Imager will not work)'
    self.fdgetdrvprm = self.fdgetdrvprm or '-1'

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Compile and run C code
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def __run_c_code (self, code):

    # create code
    fd, tmpfile = tempfile.mkstemp ('.c')
    os.write (fd, code)
    os.close (fd)
    exefile = os.path.splitext (tmpfile)[0]

    # compile
    rc = os.system ('cc -s %s -o %s >/dev/null 2>&1' % (tmpfile, exefile))
    if rc != 0:
      return None

    # run
    proc = subprocess.Popen ([exefile], stdout = subprocess.PIPE)
    return proc.communicate ()[0]

  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  # @brief Substitute configure vars (${var})
  # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  def install_in (self, path):

    # read file
    fp = open (path, 'r')
    lines = fp.readlines ()
    fp.close ()

    # replace function
    def repl (matchobj):
      name = matchobj.group (1)
      return getattr (self, name, None)

    # replace vars
    fp = open (path, 'w')
    for line in lines:
      fp.write (re.sub (r'\$\{([a-z0-9_]*?)\}', repl, line))
    fp.close ()

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Install
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
distutils.core.setup (name='mobiusft',
       cmdclass={'install' : Install},
       description='Mobius Forensic Toolkit',
       version='0.5.3',
       url='http://savannah.nongnu.org/projects/mobiusft',
       author='Eduardo Aguiar',
       author_email='eduardoaguiar@ig.com.br',
       license='GPL',
       packages=['mobius', 'mobius.extension', 'mobius.model'],
       scripts=['mobius_bin.py', 'mobius_case_update.py'],
       data_files=[('share/mobiusft', ['data/category.xml']), ('share/mobiusft/extensions', glob.glob ('extensions/*.xml'))],
	      )
