#!/usr/bin/python
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2012  Marek Marczykowski  <marmarek@invisiblethingslab.com>
#
# 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
# of the License, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#
import os
import os.path
import sys
import subprocess
import shutil
import grp
from datetime import datetime
from qubes.qubes import QubesVmCollection
from qubes.qubes import vm_files

def main():

    qvm_collection = QubesVmCollection()
    qvm_collection.lock_db_for_reading()
    qvm_collection.load()
    qvm_collection.unlock_db()

    source = os.getenv("QREXEC_REMOTE_DOMAIN")

    if source is None:
        print >> sys.stderr, 'This script must be called as qrexec service!'
        exit(1)

    source_vm = qvm_collection.get_vm_by_name(source)
    if source_vm is None:
        print >> sys.stderr, 'Domain ' + source + ' does not exist (?!)'
        exit(1)

    os.umask(0002)
    qubes_gid = grp.getgrnam('qubes').gr_gid
    
    untrusted_update_count = sys.stdin.readline(128).strip()
    if not untrusted_update_count.isdigit():
        print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: %s' % untrusted_update_count
        exit(1)
    # now sanitized
    update_count = untrusted_update_count
    if source_vm.updateable:
        # Just trust information from VM itself
        update_f = open(source_vm.dir_path + '/' + vm_files["updates_stat_file"], "w")
        update_f.write(update_count)
        update_f.close()
        try:
            os.chown(source_vm.dir_path + '/' + vm_files["updates_stat_file"], -1, qubes_gid)
        except OSError:
            pass
    elif source_vm.template is not None:
        # Hint about updates availability in template
        # If template is running - it will notify about updates itself
        if source_vm.template.is_running():
            return
        # Ignore no-updates info
        if int(update_count) > 0:
            stat_file = source_vm.template.dir_path + '/' + vm_files["updates_stat_file"]
            # If VM is started before last updates.stat - it means that updates
            # already was installed (but VM still hasn't been restarted), or other
            # VM has already notified about updates availability
            if os.path.exists(stat_file) and \
                source_vm.get_start_time() < datetime.fromtimestamp(os.path.getmtime(stat_file)):
                    return
            update_f = open(stat_file, "w")
            update_f.write(update_count)
            update_f.close()
            try:
                os.chown(stat_file, -1, qubes_gid)
            except OSError:
                pass
        else:
            print >> sys.stderr, 'Ignoring notification of no updates'

main()